v4.3.7 merge #16

Merged
blizzardfinnegan merged 2 commits from devel into stable 2023-03-13 10:20:22 -04:00
9 changed files with 223 additions and 1669 deletions

View file

@ -4,7 +4,7 @@
<groupId>org.baxter.disco</groupId>
<artifactId>ocr</artifactId>
<name>Disco OCR Accuracy Over Life Testing</name>
<version>4.3.6</version>
<version>4.3.7</version>
<description>Testing Discos for long-term accuracy, using automated optical character recognition.</description>
<organization>
<name>Baxter International</name>

View file

@ -1,474 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<XMI verified="false" xmi.version="1.2" timestamp="2023-01-23T10:03:25" xmlns:UML="http://schema.omg.org/spec/UML/1.4">
<XMI.header>
<XMI.documentation>
<XMI.exporter>umbrello uml modeller http://umbrello.kde.org</XMI.exporter>
<XMI.exporterVersion>1.6.18</XMI.exporterVersion>
<XMI.exporterEncoding>UnicodeUTF8</XMI.exporterEncoding>
</XMI.documentation>
<XMI.metamodel xmi.version="1.4" href="UML.xml" xmi.name="UML"/>
</XMI.header>
<XMI.content>
<UML:Model isSpecification="false" isAbstract="false" isLeaf="false" xmi.id="m1" isRoot="false" name="UML Model">
<UML:Namespace.ownedElement>
<UML:Stereotype visibility="public" isSpecification="false" namespace="m1" isAbstract="false" isLeaf="false" isRoot="false" xmi.id="folder" name="folder"/>
<UML:Stereotype visibility="public" isSpecification="false" namespace="m1" isAbstract="false" isLeaf="false" isRoot="false" xmi.id="interface" name="interface"/>
<UML:Stereotype visibility="public" isSpecification="false" namespace="m1" isAbstract="false" isLeaf="false" isRoot="false" xmi.id="enum" name="enum"/>
<UML:Model visibility="public" isSpecification="false" namespace="m1" isAbstract="false" isLeaf="false" isRoot="false" xmi.id="Logical_View" name="Logical View">
<UML:Namespace.ownedElement>
<UML:Package stereotype="folder" visibility="public" isSpecification="false" namespace="Logical_View" isAbstract="false" isLeaf="false" isRoot="false" xmi.id="Datatypes" name="Datatypes">
<UML:Namespace.ownedElement>
<UML:DataType visibility="public" isSpecification="false" namespace="Datatypes" isAbstract="false" isLeaf="false" isRoot="false" xmi.id="unGH1ehNX74bc" name="char"/>
<UML:DataType visibility="public" isSpecification="false" namespace="Datatypes" isAbstract="false" isLeaf="false" isRoot="false" xmi.id="uKvEIgYk9g8JI" name="int"/>
<UML:DataType visibility="public" isSpecification="false" namespace="Datatypes" isAbstract="false" isLeaf="false" isRoot="false" xmi.id="uygsbWwXhk2m1" name="float"/>
<UML:DataType visibility="public" isSpecification="false" namespace="Datatypes" isAbstract="false" isLeaf="false" isRoot="false" xmi.id="uY7bhfg6lB5uV" name="double"/>
<UML:DataType visibility="public" isSpecification="false" namespace="Datatypes" isAbstract="false" isLeaf="false" isRoot="false" xmi.id="uoZycNLqqV0ww" name="bool"/>
<UML:DataType visibility="public" isSpecification="false" namespace="Datatypes" isAbstract="false" isLeaf="false" isRoot="false" xmi.id="uONbHBGqQ9Nvv" name="string"/>
<UML:DataType visibility="public" isSpecification="false" namespace="Datatypes" isAbstract="false" isLeaf="false" isRoot="false" xmi.id="ub7ypctDu92WZ" name="unsigned char"/>
<UML:DataType visibility="public" isSpecification="false" namespace="Datatypes" isAbstract="false" isLeaf="false" isRoot="false" xmi.id="upRJjkXlPqrFh" name="signed char"/>
<UML:DataType visibility="public" isSpecification="false" namespace="Datatypes" isAbstract="false" isLeaf="false" isRoot="false" xmi.id="uDNmix9A1rSFJ" name="unsigned int"/>
<UML:DataType visibility="public" isSpecification="false" namespace="Datatypes" isAbstract="false" isLeaf="false" isRoot="false" xmi.id="u9KBxVkAp4uvL" name="signed int"/>
<UML:DataType visibility="public" isSpecification="false" namespace="Datatypes" isAbstract="false" isLeaf="false" isRoot="false" xmi.id="uanN98x2TwISy" name="short int"/>
<UML:DataType visibility="public" isSpecification="false" namespace="Datatypes" isAbstract="false" isLeaf="false" isRoot="false" xmi.id="uReJmNAio9RrE" name="unsigned short int"/>
<UML:DataType visibility="public" isSpecification="false" namespace="Datatypes" isAbstract="false" isLeaf="false" isRoot="false" xmi.id="uiFqAUDOly5yj" name="signed short int"/>
<UML:DataType visibility="public" isSpecification="false" namespace="Datatypes" isAbstract="false" isLeaf="false" isRoot="false" xmi.id="ukhRlSgv8QdFW" name="long int"/>
<UML:DataType visibility="public" isSpecification="false" namespace="Datatypes" isAbstract="false" isLeaf="false" isRoot="false" xmi.id="u6uUmJmCxhsjC" name="signed long int"/>
<UML:DataType visibility="public" isSpecification="false" namespace="Datatypes" isAbstract="false" isLeaf="false" isRoot="false" xmi.id="unsriP0Q138uN" name="unsigned long int"/>
<UML:DataType visibility="public" isSpecification="false" namespace="Datatypes" isAbstract="false" isLeaf="false" isRoot="false" xmi.id="u1QWWJqpb9m5f" name="long double"/>
<UML:DataType visibility="public" isSpecification="false" namespace="Datatypes" isAbstract="false" isLeaf="false" isRoot="false" xmi.id="uQdWUCCTWOP0y" name="wchar_t"/>
<UML:DataType visibility="public" isSpecification="false" namespace="Datatypes" isAbstract="false" isLeaf="false" isRoot="false" xmi.id="uxMhzRp06YV1R" comment="Java default List implementation" name="List"/>
<UML:DataType visibility="public" isSpecification="false" namespace="Datatypes" isAbstract="false" isLeaf="false" isRoot="false" xmi.id="u8TbzuEngzmfS" name="File"/>
<UML:DataType visibility="public" isSpecification="false" namespace="Datatypes" isAbstract="false" isLeaf="false" isRoot="false" xmi.id="umo3ql2C2Amof" comment="Imported from com.github.sarxos.webcam.Webcam&#xa;&#xa;Object for interacting with webcams." name="Webcam"/>
<UML:DataType visibility="public" isSpecification="false" namespace="Datatypes" isAbstract="false" isLeaf="false" isRoot="false" xmi.id="uGGgOwJv59ljs" name="String[]"/>
<UML:DataType visibility="public" isSpecification="false" namespace="Datatypes" isAbstract="false" isLeaf="false" isRoot="false" xmi.id="u7ht7KCJgYqdN" name="Map"/>
<UML:DataType visibility="public" isSpecification="false" namespace="Datatypes" isAbstract="false" isLeaf="false" isRoot="false" xmi.id="utlSt8DaxCIGP" name="DigitalInput"/>
<UML:DataType visibility="public" isSpecification="false" namespace="Datatypes" isAbstract="false" isLeaf="false" isRoot="false" xmi.id="uk6EygyWY8vOo" name="DigitalOutput"/>
<UML:DataType visibility="public" isSpecification="false" namespace="Datatypes" isAbstract="false" isLeaf="false" isRoot="false" xmi.id="uCuFa9fEJgiwo" name="Pwm"/>
<UML:DataType visibility="public" isSpecification="false" namespace="Datatypes" isAbstract="false" isLeaf="false" isRoot="false" xmi.id="u90UknEksNL4a" name="Frame"/>
<UML:DataType visibility="public" isSpecification="false" namespace="Datatypes" isAbstract="false" isLeaf="false" isRoot="false" xmi.id="uEFGMLeVeYyDj" name="undef"/>
</UML:Namespace.ownedElement>
</UML:Package>
<UML:Class visibility="public" isSpecification="false" namespace="Logical_View" isAbstract="false" isLeaf="false" isRoot="false" xmi.id="uqMhPoSe1k8QA" comment="Facade for Tess4J/Tesseract API&#xa;&#xa;Design complete, not yet implemented." name="TesseractFacade">
<UML:Classifier.feature>
<UML:Attribute visibility="private" isSpecification="false" xmi.id="uHbPPHt8Aepmq" type="uONbHBGqQ9Nvv" comment="NOTE:&#xa;This is copied directly from the Python class. This needs to be modified in the class itself.&#xa;&#xa;Tesseract configuration: &#xa;&#xa;Language (-l): custom language (Pro6_temp_test)&#xa;&#xa;Engine Mode (--oem): Defines performance and speed of the OCR engine. (3 autoselects, based on available hardware)&#xa;&#xa;Page Segmentation Mode (--psm): Affects how Tesseract splits images into lines of text. (7 treats the image as a single line of text)" initialValue="-l Pro6_temp_test --oem 3 --psm 7" name="CONFIG"/>
<UML:Operation visibility="public" isSpecification="false" isQuery="false" isAbstract="false" isLeaf="false" ownerScope="classifier" isRoot="false" xmi.id="umz3Tv2eyA6Cd" comment="Facade for Tess4J's TessBaseAPI.&#xa;Given an input File, this function will pass the File to Tesseract, the image will be processed. The double returned is the parsed input given by Tesseract. If Tesseract is unable to read the image, or if any error is experienced, this function will return Double.NaN" isOverride="false" name="imageToDouble" isInline="false" isVirtual="false">
<UML:BehavioralFeature.parameter>
<UML:Parameter kind="return" xmi.id="uMjS6W9J86vqg" type="uY7bhfg6lB5uV"/>
<UML:Parameter visibility="private" isSpecification="false" xmi.id="usRhAJ8rbpRdm" type="u8TbzuEngzmfS" value="" comment="The image file to be parsed" name="file"/>
</UML:BehavioralFeature.parameter>
</UML:Operation>
</UML:Classifier.feature>
</UML:Class>
<UML:Interface stereotype="interface" visibility="public" isSpecification="false" namespace="Logical_View" isAbstract="true" isLeaf="false" isRoot="false" xmi.id="um7AiVvcWgsjF" comment="Class used for interacting with Files containing images.&#xa;&#xa;Imported library" name="ImageIO">
<UML:Classifier.feature>
<UML:Operation visibility="public" isSpecification="false" isQuery="false" isAbstract="true" isLeaf="false" ownerScope="classifier" isRoot="false" xmi.id="u7QUTrR4m9Knl" comment="Writes an image using an arbitrary ImageWriter that supports the given format to an ImageOutputStream." isOverride="false" name="write" isInline="false" isVirtual="false">
<UML:BehavioralFeature.parameter>
<UML:Parameter kind="return" xmi.id="ueDW0FmDm9Q70" type="uoZycNLqqV0ww"/>
<UML:Parameter visibility="private" isSpecification="false" xmi.id="uYfBYmbboiMS1" type="uEFGMLeVeYyDj" value="" name="image"/>
<UML:Parameter visibility="private" isSpecification="false" xmi.id="uAH9HwaVeu6vf" type="uONbHBGqQ9Nvv" value="" name="formatName"/>
<UML:Parameter visibility="private" isSpecification="false" xmi.id="uinSFjfInuj4L" type="u8TbzuEngzmfS" value="" name="file"/>
</UML:BehavioralFeature.parameter>
</UML:Operation>
<UML:Operation visibility="public" isSpecification="false" isQuery="false" isAbstract="true" isLeaf="false" isRoot="false" xmi.id="u1JdCQiZpCH8p" comment="Reads an image File into a BufferedImage" isOverride="false" name="read" isInline="false" isVirtual="false">
<UML:BehavioralFeature.parameter>
<UML:Parameter kind="return" xmi.id="uyTRynw7gkVbB" type="uEFGMLeVeYyDj"/>
<UML:Parameter visibility="private" isSpecification="false" xmi.id="uQlX4qYPtt3Qa" type="u8TbzuEngzmfS" value="" name="file"/>
</UML:BehavioralFeature.parameter>
</UML:Operation>
</UML:Classifier.feature>
</UML:Interface>
<UML:Association visibility="public" isSpecification="false" namespace="Logical_View" xmi.id="u04gEi9BJjfBt" name="">
<UML:Association.connection>
<UML:AssociationEnd changeability="changeable" visibility="public" isNavigable="true" isSpecification="false" xmi.id="uGyp4BrUjj2zM" type="uqMhPoSe1k8QA" name="" aggregation="composite"/>
<UML:AssociationEnd changeability="changeable" visibility="public" isNavigable="true" isSpecification="false" xmi.id="uIxXu00M1mNAY" type="u8TbzuEngzmfS" name="" aggregation="none"/>
</UML:Association.connection>
</UML:Association>
<UML:Dependency visibility="public" isSpecification="false" namespace="Logical_View" supplier="uqMhPoSe1k8QA" xmi.id="ueBqYdCuDaOq5" client="um7AiVvcWgsjF" name=""/>
<UML:Dependency visibility="public" isSpecification="false" namespace="Logical_View" supplier="um7AiVvcWgsjF" xmi.id="ugrIUdxHOogtj" client="uqMhPoSe1k8QA" name=""/>
<UML:Class visibility="public" isSpecification="false" namespace="Logical_View" isAbstract="false" isLeaf="false" isRoot="false" xmi.id="u1dxzpJ6YJaZZ" comment="Facade over JavaCV for getting images from cameras.&#xa;&#xa;Design complete, not yet implemented." name="CameraFacade">
<UML:Classifier.feature>
<UML:Attribute visibility="private" isSpecification="false" xmi.id="uzc2k3NCdeHGs" type="uKvEIgYk9g8JI" comment="Not sure what the actual type will be for this yet, we'll see. But I'd rather not hard-code the resolution" name="CAMERA_RESOLUTION"/>
<UML:Operation visibility="public" isSpecification="false" isQuery="false" isAbstract="false" isLeaf="false" ownerScope="classifier" isRoot="false" xmi.id="uboqiQ2IGgrn6" comment="Generates Webcam objects, and returns them in a list." isOverride="false" name="listCameras" isInline="false" isVirtual="false">
<UML:BehavioralFeature.parameter>
<UML:Parameter kind="return" xmi.id="umPCY2U7E4is4" type="uxMhzRp06YV1R"/>
</UML:BehavioralFeature.parameter>
</UML:Operation>
<UML:Operation visibility="public" isSpecification="false" isQuery="false" isAbstract="false" isLeaf="false" ownerScope="classifier" isRoot="false" xmi.id="u8rQsyJtESj0k" comment="Take a picture from a given camera" isOverride="false" name="takePicture" isInline="false" isVirtual="false">
<UML:BehavioralFeature.parameter>
<UML:Parameter kind="return" xmi.id="uuTuxchLsGPjD" type="u90UknEksNL4a"/>
<UML:Parameter visibility="private" isSpecification="false" xmi.id="uRKDJmw30mXeu" type="umo3ql2C2Amof" value="" name="camera"/>
</UML:BehavioralFeature.parameter>
</UML:Operation>
<UML:Operation visibility="public" isSpecification="false" isQuery="false" isAbstract="false" isLeaf="false" ownerScope="classifier" isRoot="false" xmi.id="uTb9nmqZ3EbwA" comment="Takes several pictures in rapid succession. Returns List&lt;BufferedImage>" isOverride="false" name="pictureBurst" isInline="false" isVirtual="false">
<UML:BehavioralFeature.parameter>
<UML:Parameter kind="return" xmi.id="uY5RulRXPBOup" type="uxMhzRp06YV1R"/>
<UML:Parameter visibility="private" isSpecification="false" xmi.id="uffsSnLfERCIU" type="uKvEIgYk9g8JI" value="" comment="Number of pictures to take" name="frameCount"/>
</UML:BehavioralFeature.parameter>
</UML:Operation>
</UML:Classifier.feature>
</UML:Class>
<UML:Class visibility="public" isSpecification="false" namespace="Logical_View" isAbstract="false" isLeaf="false" isRoot="false" xmi.id="ukYbnC12j97Tq" name="OpenCVFacade">
<UML:Classifier.feature>
<UML:Operation visibility="public" isSpecification="false" isQuery="false" isAbstract="false" isLeaf="false" ownerScope="classifier" isRoot="false" xmi.id="uhnR0Lj9od5tD" comment="Crop the given BufferedImage to the given dimensions, using the input BufferedImage's getSubimage(x, y, w, h) function" isOverride="false" name="cropImage" isInline="false" isVirtual="false">
<UML:BehavioralFeature.parameter>
<UML:Parameter kind="return" xmi.id="uJfOBbDNrdmgb" type="u90UknEksNL4a"/>
<UML:Parameter visibility="private" isSpecification="false" xmi.id="u94uuOb68KFVg" type="u90UknEksNL4a" value="" comment="BufferedImage to crop" name="image"/>
<UML:Parameter visibility="private" isSpecification="false" xmi.id="uzQOK6Y25EHG6" type="uKvEIgYk9g8JI" value="" comment="X-coordinate of the upper left corner of the newly-cropped image" name="x"/>
<UML:Parameter visibility="private" isSpecification="false" xmi.id="u6ZvGbbFLKUGS" type="uKvEIgYk9g8JI" value="" comment="Y-coordinate of the top-left corner of the newly cropped image" name="y"/>
<UML:Parameter visibility="private" isSpecification="false" xmi.id="uPyRotFwGYE7j" type="uKvEIgYk9g8JI" value="" comment="Width, in pixels, of the newly cropped image" name="width"/>
<UML:Parameter visibility="private" isSpecification="false" xmi.id="uvMBinnpfg7b7" type="uKvEIgYk9g8JI" value="" comment="Height, in pixels, of the newly cropped image" name="height"/>
</UML:BehavioralFeature.parameter>
</UML:Operation>
<UML:Operation visibility="public" isSpecification="false" isQuery="false" isAbstract="false" isLeaf="false" ownerScope="classifier" isRoot="false" xmi.id="u6P8ZdhMmgO7E" comment="Puts the image through a binary threshold" isOverride="false" name="threshold" isInline="false" isVirtual="false">
<UML:BehavioralFeature.parameter>
<UML:Parameter kind="return" xmi.id="ulZ5udtVkyPMX" type="u90UknEksNL4a"/>
<UML:Parameter visibility="private" isSpecification="false" xmi.id="urY0CY2xWnZQI" type="u90UknEksNL4a" value="" comment="Image to put through the threshold" name="image"/>
</UML:BehavioralFeature.parameter>
</UML:Operation>
<UML:Operation visibility="public" isSpecification="false" isQuery="false" isAbstract="false" isLeaf="false" ownerScope="classifier" isRoot="false" xmi.id="uOU2tdo7Z41Xh" comment="Adjusts the given BufferedImage's gamma" isOverride="false" name="gammaAdjust" isInline="false" isVirtual="false">
<UML:BehavioralFeature.parameter>
<UML:Parameter kind="return" xmi.id="utJJmMtQGWrkv" type="u90UknEksNL4a"/>
<UML:Parameter visibility="private" isSpecification="false" xmi.id="uY3YHml1e6tBd" type="u90UknEksNL4a" value="" comment="Image to adjust" name="image"/>
<UML:Parameter visibility="private" isSpecification="false" xmi.id="ub8Wktj3YHdp0" type="uY7bhfg6lB5uV" value="" comment="Gamma adjustment value" name="gamma"/>
</UML:BehavioralFeature.parameter>
</UML:Operation>
<UML:Operation visibility="private" isSpecification="false" isQuery="false" isAbstract="false" isLeaf="false" ownerScope="classifier" isRoot="false" xmi.id="uyBxTNM6FtH67" comment="Performs all above-listed functions, with boolean toggles. This function will have several wrapper functions, depending on the argument count" isOverride="false" name="composeImage" isInline="false" isVirtual="false">
<UML:BehavioralFeature.parameter>
<UML:Parameter kind="return" xmi.id="u2aVQmiLCAYVm" type="u90UknEksNL4a"/>
<UML:Parameter visibility="private" isSpecification="false" xmi.id="uGytMlxbjSXSZ" type="uxMhzRp06YV1R" value="" comment="Images to be modified. Images are passed as List&lt;BufferedImages>, and are modified in sequence" name="images"/>
<UML:Parameter visibility="private" isSpecification="false" xmi.id="u6DVmlqtEd9ws" type="uoZycNLqqV0ww" value="" comment="Whether or not to use the threshold function" name="threshold"/>
<UML:Parameter visibility="private" isSpecification="false" xmi.id="uOZMOUb9qj0rQ" type="uY7bhfg6lB5uV" value="" comment="Gamma value" name="gamma"/>
<UML:Parameter visibility="private" isSpecification="false" xmi.id="u43anAkKRaHP5" type="uoZycNLqqV0ww" value="" name="gammaAdjust"/>
<UML:Parameter visibility="private" isSpecification="false" xmi.id="u5lTEWxufeOSj" type="uoZycNLqqV0ww" value="" name="crop"/>
</UML:BehavioralFeature.parameter>
</UML:Operation>
<UML:Operation visibility="public" isSpecification="false" isQuery="false" isAbstract="false" isLeaf="false" ownerScope="classifier" isRoot="false" xmi.id="usY4pLUG2i7ur" comment="Save given BufferedImage to given file location" isOverride="false" name="saveImage" isInline="false" isVirtual="false">
<UML:BehavioralFeature.parameter>
<UML:Parameter kind="return" xmi.id="uzYFAWzVyRJ47" type="uoZycNLqqV0ww"/>
<UML:Parameter visibility="private" isSpecification="false" xmi.id="uzIRLxDLwiLTJ" type="u90UknEksNL4a" value="" comment="Image to save" name="image"/>
<UML:Parameter visibility="private" isSpecification="false" xmi.id="uRzISRvfnjoTl" type="uONbHBGqQ9Nvv" value="" comment="Path to file to store the image in" name="fileLocation"/>
</UML:BehavioralFeature.parameter>
</UML:Operation>
<UML:Operation visibility="public" isSpecification="false" isQuery="false" isAbstract="false" isLeaf="false" ownerScope="classifier" isRoot="false" xmi.id="uW2zxcXVLsoSs" comment="Wrapper around several functions to process image(s) by using default config definitions in ConfigCascade. Automatically takes picture, crops if necessary, thresholds the image if necessary, adjusts the gamma as necessary, and composes the images into a final image. This image is then saved to a file, which is returned as as File. &#xa;&#xa;Returns null if an error occurs." isOverride="false" name="defaultProcessImage" isInline="false" isVirtual="false">
<UML:BehavioralFeature.parameter>
<UML:Parameter kind="return" xmi.id="uES5qCSGWu9Ty" type="u8TbzuEngzmfS"/>
<UML:Parameter visibility="private" isSpecification="false" xmi.id="uTSw9T9fNXQxO" type="uONbHBGqQ9Nvv" value="" comment="name of the camera taking the picture" name="cameraName"/>
<UML:Parameter visibility="private" isSpecification="false" xmi.id="uc7w1LgfuqqNW" type="uoZycNLqqV0ww" value="true" comment="Whether or not to crop the image" name="cropImage"/>
<UML:Parameter visibility="private" isSpecification="false" xmi.id="uaZUGYH1ix4ar" type="uoZycNLqqV0ww" value="true" comment="Whether or not to threshold the image" name="thresholdImage"/>
<UML:Parameter visibility="private" isSpecification="false" xmi.id="uSAPlDOdUrnhF" type="uoZycNLqqV0ww" value="true" comment="Whether or not to adjust the image's gamma" name="gammaAdjust"/>
<UML:Parameter visibility="private" isSpecification="false" xmi.id="uwiESoechVNdI" type="uONbHBGqQ9Nvv" value="" comment="Path to where to save the image" name="saveLocation"/>
</UML:BehavioralFeature.parameter>
</UML:Operation>
</UML:Classifier.feature>
</UML:Class>
<UML:Class visibility="public" isSpecification="false" namespace="Logical_View" isAbstract="false" isLeaf="false" isRoot="false" xmi.id="uJjuxKWEXGyzb" comment="Facade for Pi4J&#xa;&#xa;Designed and implemented (except Run Switch Interrupts)" name="MovementFacade">
<UML:Classifier.feature>
<UML:Attribute visibility="public" isSpecification="false" ownerScope="classifier" xmi.id="u9jXkL25P1C9K" type="uKvEIgYk9g8JI" comment="PWM frequency" initialValue="60000" name="FREQUENCY"/>
<UML:Attribute visibility="public" isSpecification="false" ownerScope="classifier" xmi.id="ut4DJxEPUXKfa" type="uKvEIgYk9g8JI" comment="PWM duty cycle" initialValue="50" name="DUTY_CYCLE"/>
<UML:Attribute visibility="public" isSpecification="false" ownerScope="classifier" xmi.id="u2f5fJc7U8PDh" type="uKvEIgYk9g8JI" comment="Default number of test cycles to perform" initialValue="10000" name="CYCLES"/>
<UML:Attribute visibility="public" isSpecification="false" ownerScope="classifier" xmi.id="uEdhLYHfnBmxz" type="uKvEIgYk9g8JI" comment="Maximum time in seconds to wait for a limit switch to be activated when moving." initialValue="20" name="TIME_OUT"/>
<UML:Attribute visibility="private" isSpecification="false" ownerScope="classifier" xmi.id="uEdcGAlvTefQq" type="uEFGMLeVeYyDj" comment="Motor enable pin address.&#xa;&#xa;This pin is active-high." initialValue="22" name="MOTOR_ENABLE_ADDR"/>
<UML:Attribute visibility="private" isSpecification="false" ownerScope="classifier" xmi.id="uEa6S4Xx7T82L" type="uKvEIgYk9g8JI" comment="GPIO pin address for determining motor movement direction&#xa;&#xa;Set this pin high to send the motor up.&#xa;Set this pin low to send the motor down." initialValue="27" name="MOTOR_DIRECTION_ADDR"/>
<UML:Attribute visibility="private" isSpecification="false" ownerScope="classifier" xmi.id="u8GL0Ozyhk3Ci" type="uKvEIgYk9g8JI" comment="Compressed air piston control pin address&#xa;&#xa;Setting this high extends the piston.&#xa;Setting this low retracts the piston." initialValue="15" name="PISTON_ADDR"/>
<UML:Attribute visibility="private" isSpecification="false" ownerScope="classifier" xmi.id="ulbUGU1Rekllx" type="uKvEIgYk9g8JI" comment="PWM pin address" initialValue="12" name="PWM_PIN_ADDR"/>
<UML:Attribute visibility="private" isSpecification="false" ownerScope="classifier" xmi.id="ujIpp37wSEYHO" type="uKvEIgYk9g8JI" comment="External physical run/pause switch pin address&#xa;&#xa;Test will run as long as this remains high." initialValue="10" name="RUN_SWITCH_ADDR"/>
<UML:Attribute visibility="private" isSpecification="false" ownerScope="classifier" xmi.id="uHJpn5r81B3z7" type="uKvEIgYk9g8JI" comment="Upper limit switch pin address&#xa;&#xa;When this reads high, the upper limit switch has been reached." initialValue="23" name="TOP_LIMIT_ADDR"/>
<UML:Attribute visibility="private" isSpecification="false" ownerScope="classifier" xmi.id="uOyHCaQUmsFQ7" type="uKvEIgYk9g8JI" comment="Lower limit switch pin address&#xa;&#xa;When this reads high, the lower limit switch has been reached." initialValue="24" name="BOTTOM_LIMIT_ADDR"/>
<UML:Attribute visibility="private" isSpecification="false" ownerScope="classifier" xmi.id="u6K7K4y35coSt" type="uCuFa9fEJgiwo" comment="PWM pin object" name="pwmPin"/>
<UML:Attribute visibility="private" isSpecification="false" ownerScope="classifier" xmi.id="uBodGFXo9Nndx" type="utlSt8DaxCIGP" comment="Upper limit switch pin object" name="upperLimit"/>
<UML:Attribute visibility="private" isSpecification="false" ownerScope="classifier" xmi.id="ulpGEjmhww2N0" type="utlSt8DaxCIGP" comment="Lower limit switch object" name="lowerLimit"/>
<UML:Attribute visibility="private" isSpecification="false" ownerScope="classifier" xmi.id="uC4YefTJn9iEW" type="utlSt8DaxCIGP" comment="Physical run switch object" name="runSwitch"/>
<UML:Attribute visibility="private" isSpecification="false" ownerScope="classifier" xmi.id="uYEWDteQWD2Q1" type="uk6EygyWY8vOo" comment="Motor enable pin object" name="motorEnable"/>
<UML:Attribute visibility="private" isSpecification="false" ownerScope="classifier" xmi.id="uU5tQwFEcKcC6" type="uk6EygyWY8vOo" comment="Motor direction pin object" name="motorDirection"/>
<UML:Attribute visibility="private" isSpecification="false" ownerScope="classifier" xmi.id="u4WqDqw9pt105" type="uk6EygyWY8vOo" comment="Piston movement pin object" name="piston"/>
<UML:Operation visibility="public" isSpecification="false" isQuery="false" isAbstract="false" isLeaf="false" ownerScope="classifier" isRoot="false" xmi.id="uRitO9MdiJErv" comment="Creates necessary pi4j object, initialises GPIO according to constants." isOverride="false" name="initGPIO" isInline="false" isVirtual="false"/>
<UML:Operation visibility="public" isSpecification="false" isQuery="false" isAbstract="false" isLeaf="false" ownerScope="classifier" isRoot="false" xmi.id="u6RvYZ275sv3h" comment="Closes GPIO pins. Wrapper around pi4j.shutdown()" isOverride="false" name="closeGPIO" isInline="false" isVirtual="false"/>
<UML:Operation visibility="private" isSpecification="false" isQuery="false" isAbstract="false" isLeaf="false" ownerScope="classifier" isRoot="false" xmi.id="u7lPokjezKj3b" comment="Sends the moving part of the fixture to either the upper or lower limit switch, based on input. " isOverride="false" name="gotoLimit" isInline="false" isVirtual="false">
<UML:BehavioralFeature.parameter>
<UML:Parameter kind="return" xmi.id="uHNVLlqhxJNzY" type="uoZycNLqqV0ww"/>
<UML:Parameter visibility="private" isSpecification="false" xmi.id="u1gER5bkuy4nO" type="uoZycNLqqV0ww" value="" comment="Defines whether the fixture moves up or down" name="moveUp"/>
<UML:Parameter visibility="private" isSpecification="false" xmi.id="urG19bODuaVrv" type="uKvEIgYk9g8JI" value="TIME_OUT" comment="How long to wait before giving up" name="timeout"/>
</UML:BehavioralFeature.parameter>
</UML:Operation>
<UML:Operation visibility="public" isSpecification="false" isQuery="false" isAbstract="false" isLeaf="false" ownerScope="classifier" isRoot="false" xmi.id="uvcvAkNuhAkEv" comment="Sends fixture to the lower limit " isOverride="false" name="goDown" isInline="false" isVirtual="false">
<UML:BehavioralFeature.parameter>
<UML:Parameter kind="return" xmi.id="uMvndbYpUwvIf" type="uoZycNLqqV0ww"/>
<UML:Parameter visibility="private" isSpecification="false" xmi.id="uiUt443QUOgQO" type="uKvEIgYk9g8JI" value="TIME_OUT" comment="how long to wait before giving up" name="timeout"/>
</UML:BehavioralFeature.parameter>
</UML:Operation>
<UML:Operation visibility="public" isSpecification="false" isQuery="false" isAbstract="false" isLeaf="false" ownerScope="classifier" isRoot="false" xmi.id="u1tBm05sn42fl" comment="Sends fixture to the upper limit" isOverride="false" name="goUp" isInline="false" isVirtual="false">
<UML:BehavioralFeature.parameter>
<UML:Parameter kind="return" xmi.id="uREhQNdJm1Xc1" type="uoZycNLqqV0ww"/>
<UML:Parameter visibility="private" isSpecification="false" xmi.id="ujuGngTRzsSC2" type="uKvEIgYk9g8JI" value="TIME_OUT" comment="how long to wait before giving up" name="timeout"/>
</UML:BehavioralFeature.parameter>
</UML:Operation>
<UML:Operation visibility="public" isSpecification="false" isQuery="false" isAbstract="false" isLeaf="false" ownerScope="classifier" isRoot="false" xmi.id="uQBnFo3GJFnB0" comment="Extends the compressed air piston for 1 second to press the temperature button, then retracts it" isOverride="false" name="pressButton" isInline="false" isVirtual="false"/>
<UML:Operation visibility="public" isSpecification="false" isQuery="false" isAbstract="false" isLeaf="false" ownerScope="classifier" isRoot="false" xmi.id="uXQowGHe8LlXb" comment="Pauses program flow if the physical Run switch is flipped.&#xa;&#xa;Unsure how to implement yet. We'll see." isOverride="false" name="queryRunSwitch" isInline="false" isVirtual="false"/>
<UML:Operation visibility="public" isSpecification="false" isQuery="false" isAbstract="false" isLeaf="false" ownerScope="classifier" isRoot="false" xmi.id="uShW47EjvzILh" comment="Tests the movement of all known GPIO devices." isOverride="false" name="testMovement" isInline="false" isVirtual="false"/>
</UML:Classifier.feature>
</UML:Class>
<UML:Class visibility="public" isSpecification="false" namespace="Logical_View" isAbstract="false" isLeaf="false" isRoot="false" xmi.id="ulLupzB8231re" comment="Class used to write logs and saving results to an XLSX file." name="ErrorLogging">
<UML:Classifier.feature>
<UML:Operation visibility="public" isSpecification="false" isQuery="false" isAbstract="false" isLeaf="false" ownerScope="classifier" isRoot="false" xmi.id="ulz7KMMCXsmdT" comment="Catch that an error exists, writed it to stderr and the current logfile" isOverride="false" name="logError" isInline="false" isVirtual="false"/>
</UML:Classifier.feature>
</UML:Class>
<UML:Association visibility="public" isSpecification="false" namespace="Logical_View" xmi.id="uNbEzIIZv0mis" name="">
<UML:Association.connection>
<UML:AssociationEnd changeability="changeable" visibility="public" isNavigable="false" isSpecification="false" xmi.id="u6p56uA0ZWdrW" type="uJjuxKWEXGyzb" name="" aggregation="none"/>
<UML:AssociationEnd changeability="changeable" visibility="public" isNavigable="true" isSpecification="false" xmi.id="uh9nXryIvhjvt" type="u1dxzpJ6YJaZZ" name="" aggregation="none"/>
</UML:Association.connection>
</UML:Association>
<UML:Class visibility="public" isSpecification="false" namespace="Logical_View" isAbstract="false" isLeaf="false" isRoot="false" xmi.id="uxG4FUzxo9gKu" comment="main() class" name="cli">
<UML:Classifier.feature>
<UML:Operation visibility="public" isSpecification="false" isQuery="false" isAbstract="false" isLeaf="false" ownerScope="classifier" isRoot="false" xmi.id="u8JjgzO1FnOBq" comment="Fixture moves up&#xa;Fixture moves down&#xa;Piston extends&#xa;Piston retracts&#xa;Take picture&#xa;Greyscale picture&#xa;Gamma-correct picture&#xa;Binary threshold picture&#xa;Composite pictures&#xa;Composite passed to Tesseract&#xa;Tesseract parses picture&#xa;Text from Tesseract gets put into a CSV/XLSX file" isOverride="false" name="main" isInline="false" isVirtual="false">
<UML:BehavioralFeature.parameter>
<UML:Parameter visibility="private" isSpecification="false" xmi.id="ukdxWn23wKD9t" type="uGGgOwJv59ljs" value="" name="args"/>
</UML:BehavioralFeature.parameter>
</UML:Operation>
</UML:Classifier.feature>
</UML:Class>
<UML:Class visibility="public" isSpecification="false" namespace="Logical_View" isAbstract="false" isLeaf="false" isRoot="false" xmi.id="uTYhbY1wUYfd5" comment="Facade for Apache Commons Configuration API. All internal values are stored in Maps of values, for expandability. &#xa;&#xa;Designed and written" name="ConfigFacade">
<UML:Classifier.feature>
<UML:Attribute visibility="public" isSpecification="false" ownerScope="classifier" xmi.id="uhFcuO7uJk2Ws" type="uONbHBGqQ9Nvv" comment="List&lt;String> of available camera names. This needs to be set as an unmodifiableList, so it is read-only." name="activeCameras"/>
<UML:Attribute visibility="private" isSpecification="false" ownerScope="classifier" xmi.id="uRWDjLuysWYMZ" type="u7ht7KCJgYqdN" comment="Map of available cameras. Key = camera name; value is a Map of all values. &#xa;&#xa;To get a given setting, you will need the key for both which camera, and the key for what value you need." name="config"/>
<UML:Attribute visibility="private" isSpecification="false" ownerScope="classifier" xmi.id="uZEnq8Kbd1LrY" type="uONbHBGqQ9Nvv" comment="String for file location." name="configFileDirectory"/>
<UML:Operation visibility="public" isSpecification="false" isQuery="false" isAbstract="false" isLeaf="false" ownerScope="classifier" isRoot="false" xmi.id="uRRZ1iZajAvSk" comment="Getter for any config value. Returns the value as a String; needs to be parsed into the proper type.&#xa;&#xa;Returns an empty string if any errors occur." isOverride="false" name="getValue" isInline="false" isVirtual="false">
<UML:BehavioralFeature.parameter>
<UML:Parameter kind="return" xmi.id="" type="uONbHBGqQ9Nvv"/>
<UML:Parameter visibility="private" isSpecification="false" xmi.id="u7guJXKcZ0ui4" type="u5tGbxO8iG8Iv" value="" comment="The name of the property you want the value of." name="property"/>
<UML:Parameter visibility="private" isSpecification="false" xmi.id="uOS9Bx5rjYylP" type="uONbHBGqQ9Nvv" value="" comment="Name of the camera" name="cameraName"/>
</UML:BehavioralFeature.parameter>
</UML:Operation>
<UML:Operation visibility="public" isSpecification="false" isQuery="false" isAbstract="false" isLeaf="false" ownerScope="classifier" isRoot="false" xmi.id="uZoVh5PL44Wsj" comment="Setter for available config values. Returns whether the input values were properly set." isOverride="false" name="setValue" isInline="false" isVirtual="false">
<UML:BehavioralFeature.parameter>
<UML:Parameter kind="return" xmi.id="uDl5NqeifGvyG" type="uoZycNLqqV0ww"/>
<UML:Parameter visibility="private" isSpecification="false" xmi.id="udYlH55IqPmsx" type="uONbHBGqQ9Nvv" value="" comment="Name of camera to be configured" name="camera"/>
<UML:Parameter visibility="private" isSpecification="false" xmi.id="uQCjq7LAHQrCP" type="uONbHBGqQ9Nvv" value="" comment="Name of the property to be changed" name="propertyName"/>
<UML:Parameter visibility="private" isSpecification="false" xmi.id="uuCFbj4Z4Gcxr" type="uONbHBGqQ9Nvv" value="" comment="Value the given property should be changed to. Strings are parsed into int, double, bool, or string, as necessary." name="propertyValue"/>
</UML:BehavioralFeature.parameter>
</UML:Operation>
<UML:Operation visibility="public" isSpecification="false" isQuery="false" isAbstract="false" isLeaf="false" ownerScope="classifier" isRoot="false" xmi.id="uR540dsAq0MtX" comment="Save the current configuration to a config file. Returns whether or not the file save was successful." isOverride="false" name="saveConfig" isInline="false" isVirtual="false">
<UML:BehavioralFeature.parameter>
<UML:Parameter kind="return" xmi.id="u0A21qU6rlcav" type="uoZycNLqqV0ww"/>
<UML:Parameter visibility="private" isSpecification="false" xmi.id="uUmOGrIIFdtVn" type="uONbHBGqQ9Nvv" value="configFileDirectory" comment="User-defined file location" name="filename"/>
</UML:BehavioralFeature.parameter>
</UML:Operation>
<UML:Operation visibility="public" isSpecification="false" isQuery="false" isAbstract="false" isLeaf="false" ownerScope="classifier" isRoot="false" xmi.id="u8eZZqnLYnJsZ" comment="Loads the config from the given location. " isOverride="false" name="loadConfig" isInline="false" isVirtual="false">
<UML:BehavioralFeature.parameter>
<UML:Parameter kind="return" xmi.id="u4BuivO7bxPqh" type="uoZycNLqqV0ww"/>
<UML:Parameter visibility="private" isSpecification="false" xmi.id="u5Gt5BGlPtSxB" type="uONbHBGqQ9Nvv" value="configFileDirectory" name="filepath"/>
</UML:BehavioralFeature.parameter>
</UML:Operation>
</UML:Classifier.feature>
</UML:Class>
<UML:Enumeration stereotype="enum" visibility="public" isSpecification="false" namespace="Logical_View" isAbstract="false" isLeaf="false" isRoot="false" xmi.id="u5tGbxO8iG8Iv" comment="Enum of possible config properties.&#xa;&#xa;Designed and written." name="ConfigProperties">
<UML:Enumeration.literal>
<UML:EnumerationLiteral visibility="public" isSpecification="false" namespace="u5tGbxO8iG8Iv" isAbstract="false" isLeaf="false" isRoot="false" xmi.id="udFtNckfSYvhc" value="&quot;Crop X&quot;" name="CROP_X"/>
<UML:EnumerationLiteral visibility="public" isSpecification="false" namespace="u5tGbxO8iG8Iv" isAbstract="false" isLeaf="false" isRoot="false" xmi.id="uFDj73DuzfkoM" value="&quot;Crop Y&quot;" name="CROP_Y"/>
<UML:EnumerationLiteral visibility="public" isSpecification="false" namespace="u5tGbxO8iG8Iv" isAbstract="false" isLeaf="false" isRoot="false" xmi.id="uWvRk5z0IEwsf" value="&quot;Crop Width&quot;" name="CROP_W"/>
<UML:EnumerationLiteral visibility="public" isSpecification="false" namespace="u5tGbxO8iG8Iv" isAbstract="false" isLeaf="false" isRoot="false" xmi.id="ut34PlG56PVCw" value="&quot;Crop Height&quot;" name="CROP_H"/>
<UML:EnumerationLiteral visibility="public" isSpecification="false" namespace="u5tGbxO8iG8Iv" isAbstract="false" isLeaf="false" isRoot="false" xmi.id="uRb0Mo120svKv" value="&quot;Gamma value&quot;" name="GAMMA"/>
<UML:EnumerationLiteral visibility="public" isSpecification="false" namespace="u5tGbxO8iG8Iv" isAbstract="false" isLeaf="false" isRoot="false" xmi.id="uCzabsPIKF2fr" value="&quot;Composite frame count&quot;" name="COMPOSITE_FRAMES"/>
<UML:EnumerationLiteral visibility="public" isSpecification="false" namespace="u5tGbxO8iG8Iv" isAbstract="false" isLeaf="false" isRoot="false" xmi.id="ujXL34ZRbqZ9t" value="&quot;Prime device?&quot;" name="PRIME"/>
</UML:Enumeration.literal>
</UML:Enumeration>
<UML:Association visibility="public" isSpecification="false" namespace="Logical_View" xmi.id="uZpX5Dw6MUhVF" name="">
<UML:Association.connection>
<UML:AssociationEnd changeability="changeable" visibility="public" isNavigable="true" isSpecification="false" xmi.id="uuhpkwj6f0CLO" type="uTYhbY1wUYfd5" name="" aggregation="composite"/>
<UML:AssociationEnd changeability="changeable" visibility="public" isNavigable="true" isSpecification="false" xmi.id="uf2sBOHTYudgr" type="u5tGbxO8iG8Iv" name="" aggregation="none"/>
</UML:Association.connection>
</UML:Association>
<UML:Class visibility="public" isSpecification="false" namespace="Logical_View" isAbstract="false" isLeaf="false" isRoot="false" xmi.id="uLsx1LzuxKTQk" name="DataSaving">
<UML:Classifier.feature>
<UML:Attribute visibility="public" isSpecification="false" ownerScope="classifier" xmi.id="utZ98UQw7GOj6" type="uONbHBGqQ9Nvv" comment="Path to Excel file" name="excelFile"/>
<UML:Operation visibility="public" isSpecification="false" isQuery="false" isAbstract="false" isLeaf="false" ownerScope="classifier" isRoot="false" xmi.id="uJ0oNZhpsFIB1" comment="Writes next line to XLSX file. Returns bool of whether the write was successful.&#xa;&#xa;For backwards compatibility, this requires storage of the path to the log file, and a system call to get the current date and time." isOverride="false" name="writeValues" isInline="false" isVirtual="false">
<UML:BehavioralFeature.parameter>
<UML:Parameter kind="return" xmi.id="uwJLj5H6CFdVD" type="uoZycNLqqV0ww"/>
<UML:Parameter visibility="private" isSpecification="false" xmi.id="uAW4oPF9oLcLJ" type="uKvEIgYk9g8JI" value="" name="cycle"/>
<UML:Parameter visibility="private" isSpecification="false" xmi.id="uHjGXNjaMMTW0" type="uY7bhfg6lB5uV" value="" comment="Camera1 OCR result" name="cam1Result"/>
<UML:Parameter visibility="private" isSpecification="false" xmi.id="u2wK1WY6lNqdf" type="uONbHBGqQ9Nvv" value="" comment="Path to relevant image file for Cam1" name="cam1Image"/>
<UML:Parameter visibility="private" isSpecification="false" xmi.id="uo79v03e4isNM" type="uY7bhfg6lB5uV" value="" comment="Camera2 OCR result" name="cam2Result"/>
<UML:Parameter visibility="private" isSpecification="false" xmi.id="uLtbrf4aZe1HH" type="uONbHBGqQ9Nvv" value="" comment="Path to relevant image for Cam2" name="cam2Image"/>
</UML:BehavioralFeature.parameter>
</UML:Operation>
</UML:Classifier.feature>
</UML:Class>
</UML:Namespace.ownedElement>
<XMI.extension xmi.extender="umbrello">
<diagrams resolution="192">
<diagram showopsig="1" linecolor="#ff0000" snapx="25" showattribassocs="1" snapy="25" linewidth="0" showattsig="1" textcolor="#000000" isopen="1" showpackage="1" showpubliconly="0" showstereotype="1" name="class diagram" font="72,9,-1,5,50,0,0,0,0,0" canvasheight="2425.96" canvaswidth="4707.18" localid="-1" snapcsgrid="0" showgrid="0" showops="1" griddotcolor="#f6f6f6" backgroundcolor="#ffffff" usefillcolor="1" fillcolor="#ffffc0" zoom="53.50250105473708" xmi.id="unReUR2YloiR7" documentation="" showscope="1" snapgrid="0" showatts="1" type="1">
<widgets>
<classwidget linecolor="#ff0000" usesdiagramfillcolor="0" linewidth="0" textcolor="#000000" showoperations="1" usesdiagramusefillcolor="0" showpubliconly="0" showpackage="1" x="2397.35" showattsigs="601" showstereotype="1" y="991.929" showattributes="1" font="72,12,-1,5,50,0,0,0,0,0" localid="u8zNPcHt4r37E" width="783" isinstance="0" usefillcolor="1" fillcolor="#ffffc0" xmi.id="uqMhPoSe1k8QA" autoresize="1" showscope="1" height="111" showopsigs="601"/>
<interfacewidget linecolor="#ff0000" usesdiagramfillcolor="0" linewidth="0" textcolor="#000000" showoperations="1" usesdiagramusefillcolor="0" showpubliconly="0" showpackage="0" x="2979.31" showattsigs="601" showstereotype="1" y="1721.16" showattributes="0" font="72,12,-1,5,50,0,0,0,0,0" drawascircle="0" localid="uX9qoYww8INRA" width="847" isinstance="0" usefillcolor="1" fillcolor="#ffffc0" xmi.id="um7AiVvcWgsjF" autoresize="1" showscope="1" height="148" showopsigs="601"/>
<classwidget linecolor="#ff0000" usesdiagramfillcolor="0" linewidth="0" textcolor="#000000" showoperations="1" usesdiagramusefillcolor="0" showpubliconly="0" showpackage="1" x="3236.34" showattsigs="601" showstereotype="1" y="918.46" showattributes="1" font="72,12,-1,5,50,0,0,0,0,0" localid="ut6gHdqePmykD" width="589" isinstance="0" usefillcolor="1" fillcolor="#ffffc0" xmi.id="u1dxzpJ6YJaZZ" autoresize="1" showscope="1" height="185" showopsigs="601"/>
<classwidget linecolor="#ff0000" usesdiagramfillcolor="0" linewidth="0" textcolor="#000000" showoperations="1" usesdiagramusefillcolor="0" showpubliconly="0" showpackage="1" x="6104.53" showattsigs="601" showstereotype="1" y="738.37" showattributes="1" font="72,12,-1,5,50,0,0,0,0,0" localid="uNm72yGqlA9lS" width="1000" isinstance="0" usefillcolor="1" fillcolor="#ffffc0" xmi.id="ukYbnC12j97Tq" autoresize="1" showscope="1" height="277" showopsigs="601"/>
<classwidget linecolor="#ff0000" usesdiagramfillcolor="0" linewidth="0" textcolor="#000000" showoperations="1" usesdiagramusefillcolor="0" showpubliconly="0" showpackage="1" x="5171.42" showattsigs="601" showstereotype="1" y="814.678" showattributes="1" font="72,12,-1,5,50,0,0,0,0,0" localid="u64rTnKBAIVPH" width="857" isinstance="0" usefillcolor="1" fillcolor="#ffffc0" xmi.id="uJjuxKWEXGyzb" autoresize="1" showscope="1" height="999" showopsigs="601"/>
<classwidget linecolor="#ff0000" usesdiagramfillcolor="0" linewidth="0" textcolor="#000000" showoperations="1" usesdiagramusefillcolor="0" showpubliconly="0" showpackage="1" x="3907.44" showattsigs="601" showstereotype="1" y="617.38" showattributes="1" font="72,12,-1,5,50,0,0,0,0,0" localid="utl1KR7Bq1aFN" width="207" isinstance="0" usefillcolor="1" fillcolor="#ffffc0" xmi.id="ulLupzB8231re" autoresize="1" showscope="1" height="92" showopsigs="601"/>
<classwidget linecolor="#ff0000" usesdiagramfillcolor="0" linewidth="0" textcolor="#000000" showoperations="1" usesdiagramusefillcolor="0" showpubliconly="0" showpackage="1" x="4521.16" showattsigs="601" showstereotype="1" y="12.2243" showattributes="1" font="72,12,-1,5,50,0,0,0,0,0" localid="u3s8hWaa9IySG" width="317" isinstance="0" usefillcolor="1" fillcolor="#ffffc0" xmi.id="uxG4FUzxo9gKu" autoresize="1" showscope="1" height="92" showopsigs="601"/>
<classwidget linecolor="#ff0000" usesdiagramfillcolor="0" linewidth="0" textcolor="#000000" showoperations="1" usesdiagramusefillcolor="0" showpubliconly="0" showpackage="1" x="2588.4" showattsigs="601" showstereotype="1" y="146.804" showattributes="1" font="72,12,-1,5,50,0,0,0,0,0" localid="upZUt3HdJywQE" width="1000" isinstance="0" usefillcolor="1" fillcolor="#ffffc0" xmi.id="uTYhbY1wUYfd5" autoresize="1" showscope="1" height="296" showopsigs="601"/>
<enumwidget linecolor="#ff0000" usesdiagramfillcolor="0" linewidth="0" textcolor="#000000" usesdiagramusefillcolor="0" showpackage="1" x="2722.23" showstereotype="1" y="-556.797" font="72,12,-1,5,50,0,0,0,0,0" localid="uI1wUQvO6NV3T" width="726" isinstance="0" usefillcolor="1" fillcolor="#ffffc0" xmi.id="u5tGbxO8iG8Iv" autoresize="1" height="370"/>
<classwidget linecolor="#ff0000" usesdiagramfillcolor="0" linewidth="0" textcolor="#000000" showoperations="1" usesdiagramusefillcolor="0" showpubliconly="0" showpackage="1" x="4259.24" showattsigs="601" showstereotype="1" y="610.887" showattributes="1" font="72,12,-1,5,50,0,0,0,0,0" localid="uOvpQbyzquusg" width="1000" isinstance="0" usefillcolor="1" fillcolor="#ffffc0" xmi.id="uLsx1LzuxKTQk" autoresize="1" showscope="1" height="111" showopsigs="601"/>
</widgets>
<messages/>
<associations>
<assocwidget indexa="1" linecolor="#ff0000" usesdiagramfillcolor="1" widgetbid="um7AiVvcWgsjF" indexb="1" linewidth="0" seqnum="" textcolor="none" usesdiagramusefillcolor="1" totalcounta="2" totalcountb="2" widgetaid="uqMhPoSe1k8QA" font="72,9,-1,5,50,0,0,0,0,0" localid="uopLUatHg2QN2" usefillcolor="1" fillcolor="none" xmi.id="ugrIUdxHOogtj" autoresize="1" type="502">
<linepath layout="Direct">
<startpoint startx="3180.35" starty="1102.93"/>
<endpoint endx="3180.35" endy="1721.16"/>
</linepath>
</assocwidget>
<assocwidget indexa="1" linecolor="#ff0000" usesdiagramfillcolor="1" widgetbid="u5tGbxO8iG8Iv" indexb="1" linewidth="0" seqnum="" textcolor="none" usesdiagramusefillcolor="1" totalcounta="2" totalcountb="2" widgetaid="uTYhbY1wUYfd5" font="72,9,-1,5,50,0,0,0,0,0" localid="uwL5PsqAoqxkQ" usefillcolor="1" fillcolor="none" xmi.id="uZpX5Dw6MUhVF" autoresize="1" type="510">
<linepath layout="Direct">
<startpoint startx="2897.74" starty="146.804"/>
<endpoint endx="2897.74" endy="-186.797"/>
</linepath>
</assocwidget>
</associations>
</diagram>
</diagrams>
</XMI.extension>
</UML:Model>
<UML:Model visibility="public" isSpecification="false" namespace="m1" isAbstract="false" isLeaf="false" isRoot="false" xmi.id="Use_Case_View" name="Use Case View">
<UML:Namespace.ownedElement/>
</UML:Model>
<UML:Model visibility="public" isSpecification="false" namespace="m1" isAbstract="false" isLeaf="false" isRoot="false" xmi.id="Component_View" name="Component View">
<UML:Namespace.ownedElement/>
</UML:Model>
<UML:Model visibility="public" isSpecification="false" namespace="m1" isAbstract="false" isLeaf="false" isRoot="false" xmi.id="Deployment_View" name="Deployment View">
<UML:Namespace.ownedElement/>
</UML:Model>
<UML:Model visibility="public" isSpecification="false" namespace="m1" isAbstract="false" isLeaf="false" isRoot="false" xmi.id="Entity_Relationship_Model" name="Entity Relationship Model">
<UML:Namespace.ownedElement/>
</UML:Model>
</UML:Namespace.ownedElement>
</UML:Model>
</XMI.content>
<XMI.extensions xmi.extender="umbrello">
<docsettings viewid="unReUR2YloiR7" uniqueid="uN7lzxa2HJ4f3" documentation=""/>
<listview>
<listitem open="1" type="800" id="Views">
<listitem open="1" type="821" id="Component_View"/>
<listitem open="1" type="827" id="Deployment_View"/>
<listitem open="1" type="836" id="Entity_Relationship_Model"/>
<listitem open="1" type="801" id="Logical_View">
<listitem open="0" type="813" id="u1dxzpJ6YJaZZ">
<listitem open="0" type="814" id="uzc2k3NCdeHGs"/>
<listitem open="0" type="815" id="uboqiQ2IGgrn6"/>
<listitem open="0" type="815" id="uTb9nmqZ3EbwA"/>
<listitem open="0" type="815" id="u8rQsyJtESj0k"/>
</listitem>
<listitem open="0" type="807" id="unReUR2YloiR7" label="class diagram"/>
<listitem open="0" type="813" id="uxG4FUzxo9gKu">
<listitem open="0" type="815" id="u8JjgzO1FnOBq"/>
</listitem>
<listitem open="1" type="813" id="uTYhbY1wUYfd5">
<listitem open="0" type="814" id="uhFcuO7uJk2Ws"/>
<listitem open="0" type="814" id="uRWDjLuysWYMZ"/>
<listitem open="0" type="814" id="uZEnq8Kbd1LrY"/>
<listitem open="0" type="815" id="uRRZ1iZajAvSk"/>
<listitem open="0" type="815" id="u8eZZqnLYnJsZ"/>
<listitem open="0" type="815" id="uR540dsAq0MtX"/>
<listitem open="0" type="815" id="uZoVh5PL44Wsj"/>
</listitem>
<listitem open="1" type="831" id="u5tGbxO8iG8Iv">
<listitem open="0" type="839" id="uCzabsPIKF2fr"/>
<listitem open="0" type="839" id="ut34PlG56PVCw"/>
<listitem open="0" type="839" id="uWvRk5z0IEwsf"/>
<listitem open="0" type="839" id="udFtNckfSYvhc"/>
<listitem open="0" type="839" id="uFDj73DuzfkoM"/>
<listitem open="0" type="839" id="uRb0Mo120svKv"/>
<listitem open="0" type="839" id="ujXL34ZRbqZ9t"/>
</listitem>
<listitem open="1" type="813" id="uLsx1LzuxKTQk">
<listitem open="0" type="814" id="utZ98UQw7GOj6"/>
<listitem open="0" type="815" id="uJ0oNZhpsFIB1"/>
</listitem>
<listitem open="0" type="830" id="Datatypes">
<listitem open="0" type="829" id="uoZycNLqqV0ww"/>
<listitem open="0" type="829" id="unGH1ehNX74bc"/>
<listitem open="1" type="829" id="utlSt8DaxCIGP"/>
<listitem open="1" type="829" id="uk6EygyWY8vOo"/>
<listitem open="0" type="829" id="uY7bhfg6lB5uV"/>
<listitem open="1" type="829" id="u8TbzuEngzmfS"/>
<listitem open="0" type="829" id="uygsbWwXhk2m1"/>
<listitem open="1" type="829" id="u90UknEksNL4a"/>
<listitem open="0" type="829" id="uKvEIgYk9g8JI"/>
<listitem open="1" type="829" id="uxMhzRp06YV1R"/>
<listitem open="0" type="829" id="u1QWWJqpb9m5f"/>
<listitem open="0" type="829" id="ukhRlSgv8QdFW"/>
<listitem open="1" type="829" id="u7ht7KCJgYqdN"/>
<listitem open="1" type="829" id="uCuFa9fEJgiwo"/>
<listitem open="0" type="829" id="uanN98x2TwISy"/>
<listitem open="0" type="829" id="upRJjkXlPqrFh"/>
<listitem open="0" type="829" id="u9KBxVkAp4uvL"/>
<listitem open="0" type="829" id="u6uUmJmCxhsjC"/>
<listitem open="0" type="829" id="uiFqAUDOly5yj"/>
<listitem open="0" type="829" id="uONbHBGqQ9Nvv"/>
<listitem open="1" type="829" id="uGGgOwJv59ljs"/>
<listitem open="0" type="829" id="uEFGMLeVeYyDj"/>
<listitem open="0" type="829" id="ub7ypctDu92WZ"/>
<listitem open="0" type="829" id="uDNmix9A1rSFJ"/>
<listitem open="0" type="829" id="unsriP0Q138uN"/>
<listitem open="0" type="829" id="uReJmNAio9RrE"/>
<listitem open="0" type="829" id="uQdWUCCTWOP0y"/>
<listitem open="1" type="829" id="umo3ql2C2Amof"/>
</listitem>
<listitem open="0" type="813" id="ulLupzB8231re">
<listitem open="0" type="815" id="ulz7KMMCXsmdT"/>
</listitem>
<listitem open="0" type="817" id="um7AiVvcWgsjF">
<listitem open="0" type="815" id="u1JdCQiZpCH8p"/>
<listitem open="0" type="815" id="u7QUTrR4m9Knl"/>
</listitem>
<listitem open="0" type="813" id="uJjuxKWEXGyzb">
<listitem open="0" type="814" id="uOyHCaQUmsFQ7"/>
<listitem open="0" type="815" id="u6RvYZ275sv3h"/>
<listitem open="0" type="814" id="u2f5fJc7U8PDh"/>
<listitem open="0" type="814" id="ut4DJxEPUXKfa"/>
<listitem open="0" type="814" id="u9jXkL25P1C9K"/>
<listitem open="0" type="815" id="uvcvAkNuhAkEv"/>
<listitem open="0" type="815" id="u7lPokjezKj3b"/>
<listitem open="0" type="815" id="u1tBm05sn42fl"/>
<listitem open="0" type="815" id="uRitO9MdiJErv"/>
<listitem open="0" type="814" id="ulpGEjmhww2N0"/>
<listitem open="0" type="814" id="uEa6S4Xx7T82L"/>
<listitem open="0" type="814" id="uEdcGAlvTefQq"/>
<listitem open="0" type="814" id="uU5tQwFEcKcC6"/>
<listitem open="0" type="814" id="uYEWDteQWD2Q1"/>
<listitem open="0" type="814" id="u4WqDqw9pt105"/>
<listitem open="0" type="814" id="u8GL0Ozyhk3Ci"/>
<listitem open="0" type="815" id="uQBnFo3GJFnB0"/>
<listitem open="0" type="814" id="ulbUGU1Rekllx"/>
<listitem open="0" type="814" id="u6K7K4y35coSt"/>
<listitem open="0" type="815" id="uXQowGHe8LlXb"/>
<listitem open="0" type="814" id="ujIpp37wSEYHO"/>
<listitem open="0" type="814" id="uC4YefTJn9iEW"/>
<listitem open="0" type="815" id="uShW47EjvzILh"/>
<listitem open="0" type="814" id="uEdhLYHfnBmxz"/>
<listitem open="0" type="814" id="uHJpn5r81B3z7"/>
<listitem open="0" type="814" id="uBodGFXo9Nndx"/>
</listitem>
<listitem open="1" type="813" id="ukYbnC12j97Tq">
<listitem open="0" type="815" id="uyBxTNM6FtH67"/>
<listitem open="0" type="815" id="uhnR0Lj9od5tD"/>
<listitem open="0" type="815" id="uW2zxcXVLsoSs"/>
<listitem open="0" type="815" id="uOU2tdo7Z41Xh"/>
<listitem open="0" type="815" id="usY4pLUG2i7ur"/>
<listitem open="0" type="815" id="u6P8ZdhMmgO7E"/>
</listitem>
<listitem open="0" type="813" id="uqMhPoSe1k8QA">
<listitem open="0" type="814" id="uHbPPHt8Aepmq"/>
<listitem open="0" type="815" id="umz3Tv2eyA6Cd"/>
</listitem>
</listitem>
<listitem open="1" type="802" id="Use_Case_View"/>
</listitem>
</listview>
<codegeneration>
<codegenerator language="C++">
<sourcecode value="//Output config&#xa;var motorEnableConfig = DigitalOutput&#xa; .newConfigBuilder(pi4j)&#xa;&#x9; .address(MOTOR_ENABLE)&#xa; .shutdown(DigitalState.LOW)&#xa; .initial(DigitalState.LOW)&#xa; .build();&#xa;&#xa;//Output pin creation&#xa;var motorEnable = pi4j.create(motorEnableConfig);&#xa;&#xa;//Input config&#xa;var topLimitConfig = DigitalInput.newConfigBuilder(pi4j).address(TOP_LIMIT).pull(PullResistance.PULL_DOWN);&#xa;&#xa;//Input pin creation&#xa;var topLimit = pi4j.create(topLimitConfig);&#xa;&#xa;//PWM setup&#xa;var pwmConfig = Pwm newConfigBuilder(pi4j).address(PWM_PIN).pwmType(PwmType.HARDWARE).shutdown(0).initial(DUTY_CYCLE).build();&#xa;&#xa;//PWM pin creation&#xa;var pwmPin = pi4j.create(config);" id="uRitO9MdiJErv"/>
<sourcecode value="pi4j.shutdown();" id="u6RvYZ275sv3h"/>
</codegenerator>
</codegeneration>
</XMI.extensions>
</XMI>

View file

@ -3,7 +3,7 @@
<modelVersion>4.0.0</modelVersion>
<groupId>org.baxter.disco</groupId>
<artifactId>ocr</artifactId>
<version>4.3.6</version>
<version>4.3.7</version>
<packaging>jar</packaging>
<name>Disco OCR Accuracy Over Life Testing</name>
<description>Testing Discos for long-term accuracy, using automated optical character recognition.</description>
@ -186,7 +186,7 @@
<version>3.4.1</version>
<!--<configuration>
<show>private</show>
</configuration> -->
</configuration>-->
</plugin>
</plugins>
</reporting>

View file

@ -1,920 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<XMI verified="false" xmi.version="1.2" timestamp="2023-01-17T08:11:41" xmlns:UML="http://schema.omg.org/spec/UML/1.4">
<XMI.header>
<XMI.documentation>
<XMI.exporter>umbrello uml modeller http://umbrello.kde.org</XMI.exporter>
<XMI.exporterVersion>1.6.18</XMI.exporterVersion>
<XMI.exporterEncoding>UnicodeUTF8</XMI.exporterEncoding>
</XMI.documentation>
<XMI.metamodel xmi.version="1.4" href="UML.xml" xmi.name="UML"/>
</XMI.header>
<XMI.content>
<UML:Model isSpecification="false" isAbstract="false" isLeaf="false" xmi.id="m1" isRoot="false" name="UML Model">
<UML:Namespace.ownedElement>
<UML:Stereotype visibility="public" isSpecification="false" namespace="m1" isAbstract="false" isLeaf="false" isRoot="false" xmi.id="folder" name="folder"/>
<UML:Stereotype visibility="public" isSpecification="false" namespace="m1" isAbstract="false" isLeaf="false" isRoot="false" xmi.id="interface" name="interface"/>
<UML:Stereotype visibility="public" isSpecification="false" namespace="m1" isAbstract="false" isLeaf="false" isRoot="false" xmi.id="enum" name="enum"/>
<UML:Model visibility="public" isSpecification="false" namespace="m1" isAbstract="false" isLeaf="false" isRoot="false" xmi.id="Logical_View" name="Logical View">
<UML:Namespace.ownedElement>
<UML:Package stereotype="folder" visibility="public" isSpecification="false" namespace="Logical_View" isAbstract="false" isLeaf="false" isRoot="false" xmi.id="Datatypes" name="Datatypes">
<UML:Namespace.ownedElement>
<UML:DataType visibility="public" isSpecification="false" namespace="Datatypes" isAbstract="false" isLeaf="false" isRoot="false" xmi.id="uWD0LCe31Qe6z" name="char"/>
<UML:DataType visibility="public" isSpecification="false" namespace="Datatypes" isAbstract="false" isLeaf="false" isRoot="false" xmi.id="uC8n0yHzYaFtW" name="int"/>
<UML:DataType visibility="public" isSpecification="false" namespace="Datatypes" isAbstract="false" isLeaf="false" isRoot="false" xmi.id="ut3U2TtHTDMqm" name="float"/>
<UML:DataType visibility="public" isSpecification="false" namespace="Datatypes" isAbstract="false" isLeaf="false" isRoot="false" xmi.id="uivFEqo1zOYsW" name="double"/>
<UML:DataType visibility="public" isSpecification="false" namespace="Datatypes" isAbstract="false" isLeaf="false" isRoot="false" xmi.id="uzncWu1t5XAqV" name="bool"/>
<UML:DataType visibility="public" isSpecification="false" namespace="Datatypes" isAbstract="false" isLeaf="false" isRoot="false" xmi.id="ufgglRaUHqAMn" name="string"/>
<UML:DataType visibility="public" isSpecification="false" namespace="Datatypes" isAbstract="false" isLeaf="false" isRoot="false" xmi.id="uqO664Buw0Nbg" name="unsigned char"/>
<UML:DataType visibility="public" isSpecification="false" namespace="Datatypes" isAbstract="false" isLeaf="false" isRoot="false" xmi.id="uvnmQ4VudFICo" name="signed char"/>
<UML:DataType visibility="public" isSpecification="false" namespace="Datatypes" isAbstract="false" isLeaf="false" isRoot="false" xmi.id="uAbtVeD2yGn1P" name="unsigned int"/>
<UML:DataType visibility="public" isSpecification="false" namespace="Datatypes" isAbstract="false" isLeaf="false" isRoot="false" xmi.id="uYBWUNRPEoBmu" name="signed int"/>
<UML:DataType visibility="public" isSpecification="false" namespace="Datatypes" isAbstract="false" isLeaf="false" isRoot="false" xmi.id="uXwBFpyqikx4b" name="short int"/>
<UML:DataType visibility="public" isSpecification="false" namespace="Datatypes" isAbstract="false" isLeaf="false" isRoot="false" xmi.id="uNS8ituxzmJ7d" name="unsigned short int"/>
<UML:DataType visibility="public" isSpecification="false" namespace="Datatypes" isAbstract="false" isLeaf="false" isRoot="false" xmi.id="uwf3jLNyYyCZ7" name="signed short int"/>
<UML:DataType visibility="public" isSpecification="false" namespace="Datatypes" isAbstract="false" isLeaf="false" isRoot="false" xmi.id="uhStEw218vtpA" name="long int"/>
<UML:DataType visibility="public" isSpecification="false" namespace="Datatypes" isAbstract="false" isLeaf="false" isRoot="false" xmi.id="uPqdLsqMUsaYG" name="signed long int"/>
<UML:DataType visibility="public" isSpecification="false" namespace="Datatypes" isAbstract="false" isLeaf="false" isRoot="false" xmi.id="uUeccgrWVodPs" name="unsigned long int"/>
<UML:DataType visibility="public" isSpecification="false" namespace="Datatypes" isAbstract="false" isLeaf="false" isRoot="false" xmi.id="usVn8H52hL2Et" name="long double"/>
<UML:DataType visibility="public" isSpecification="false" namespace="Datatypes" isAbstract="false" isLeaf="false" isRoot="false" xmi.id="u5k9vnaRqpOn5" name="wchar_t"/>
<UML:DataType visibility="public" isSpecification="false" namespace="Datatypes" isAbstract="false" isLeaf="false" isRoot="false" xmi.id="uSN9tVhGt4JeL" comment="Java and Python's List implementations seem fairly compatible with each other." name="List"/>
<UML:DataType visibility="public" isSpecification="false" namespace="Datatypes" isAbstract="false" isLeaf="false" isRoot="false" xmi.id="unEKbNBpRDYxe" comment="In the current implementation, these are dictionaries. Java's rough equivalent are Maps. " name="Map"/>
<UML:DataType visibility="public" isSpecification="false" namespace="Datatypes" isAbstract="false" isLeaf="false" isRoot="false" xmi.id="uWZbdMIa5lsbb" comment="The current implementation in Python uses a List. While Java Lists have the same functionality as Python's, the code implemented in the Python seems to be more fit for a Queue than a List." name="Queue"/>
<UML:DataType visibility="public" isSpecification="false" namespace="Datatypes" isAbstract="false" isLeaf="false" isRoot="false" xmi.id="ue6uiThNgNDFB" comment="In python, this is an ndarray (imported from numpy). I'm assuming this will act similarly to an ArrayList, or a nested array in Java." name="int[][]"/>
<UML:DataType visibility="public" isSpecification="false" namespace="Datatypes" isAbstract="false" isLeaf="false" isRoot="false" xmi.id="uQ6I6JzsO2HGl" comment="The object type used to communicate with the Raspberry Pis GPIO pins." name="Pi"/>
<UML:DataType visibility="public" isSpecification="false" namespace="Datatypes" isAbstract="false" isLeaf="false" isRoot="false" xmi.id="uDw2wLV7OL4hx" comment="OpenCV class for interacting with camera streams" name="VideoCapture"/>
<UML:DataType visibility="public" isSpecification="false" namespace="Datatypes" isAbstract="false" isLeaf="false" isRoot="false" xmi.id="urdHVFlCDEbzy" name="undef"/>
</UML:Namespace.ownedElement>
</UML:Package>
<UML:Class visibility="public" isSpecification="false" namespace="Logical_View" isAbstract="false" isLeaf="false" isRoot="false" xmi.id="uzwE2u8G0m86m" comment="Abstraction layer for interaction with Tesseract." name="ocr">
<UML:Classifier.feature>
<UML:Attribute visibility="private" isSpecification="false" ownerScope="classifier" xmi.id="udLhM9iyVlr22" type="ufgglRaUHqAMn" comment="Tesseract configuration:&#xa;&#xa;Language (-l): custom language (Pro6_temp_test)&#xa;&#xa;Engine Mode (--oem): Defines performance and speed of the OCR engine. (3 autoselects, based on available hardware)&#xa;&#xa;Page Segmentation Mode (--psm): Affects how Tesseract splits images into lines of text. (7 treats the image as a single line of text)" initialValue="-l Pro6_temp_test --oem 3 --psm 7" name="CONFIG"/>
<UML:Operation visibility="public" isSpecification="false" isQuery="false" isAbstract="false" isLeaf="false" ownerScope="classifier" isRoot="false" xmi.id="uKEsgcOL0LOOO" comment="Converts an image into an OCR-parsed string, according to a given config. &#xa;Does some minor post-processing to standardise output into a 3 digit number, with a decimal point, where possible." isOverride="false" name="read_img" isInline="false" isVirtual="false">
<UML:BehavioralFeature.parameter>
<UML:Parameter kind="return" xmi.id="uv4rKVHI9PtMq" type="ufgglRaUHqAMn"/>
<UML:Parameter visibility="private" isSpecification="false" xmi.id="uT4N6YpWhDvhT" type="urdHVFlCDEbzy" value="" comment="The image, as greyscale values. 255 = white, 0 = black. " name="img"/>
<UML:Parameter visibility="private" isSpecification="false" xmi.id="uuoHirewwRT4y" type="ufgglRaUHqAMn" value="CONFIG" comment="Tesseract config string. &#xa;For default, see definition of CONFIG variable in this class." name="config"/>
</UML:BehavioralFeature.parameter>
</UML:Operation>
</UML:Classifier.feature>
</UML:Class>
<UML:Class visibility="public" isSpecification="false" namespace="Logical_View" isAbstract="false" isLeaf="false" isRoot="false" xmi.id="uoU85LGuFdMDB" comment="Abstraction of GPIO pins into human-readable instructions." name="fixture_gpio">
<UML:Classifier.feature>
<UML:Attribute visibility="private" isSpecification="false" xmi.id="ulkS8k9zQQLaM" type="uC8n0yHzYaFtW" comment="PWM Frequency" initialValue="60000" name="FREQ"/>
<UML:Attribute visibility="private" isSpecification="false" xmi.id="uOerTnEHIUx5L" type="uC8n0yHzYaFtW" comment="PWM Duty Cycle" initialValue="50" name="DUTY"/>
<UML:Attribute visibility="private" isSpecification="false" xmi.id="uaBNa9sS4Wa2g" type="uC8n0yHzYaFtW" comment="Number of tests to perform" initialValue="10000" name="CYCLES"/>
<UML:Attribute visibility="private" isSpecification="false" xmi.id="ux3CpaWDBIAvf" type="uC8n0yHzYaFtW" comment="Number of seconds to wait for a limit switch to be toggled, when moving the fixture up or down." initialValue="20" name="TIME_OUT"/>
<UML:Attribute visibility="private" isSpecification="false" xmi.id="u1YkYmMVBAI19" type="uC8n0yHzYaFtW" comment="BCM-Mode GPIO pin for the motor enable. This is the motor that moves the fixture up and down. Setting this pin to be high turns the motor on, while setting this pin low turns the motor off." initialValue="22" name="MOTOR_ENA"/>
<UML:Attribute visibility="private" isSpecification="false" xmi.id="uuN4wnwIerM4o" type="uC8n0yHzYaFtW" comment="BCM-mode GPIO pin for defining motor direction.&#xa;Forcing this pin high will tell the fixture to move upwards, while forcing this pin low will tell the fixture to move down." initialValue="27" name="MOTOR_DIR"/>
<UML:Attribute visibility="private" isSpecification="false" xmi.id="unkWUm0O7ndTU" type="uC8n0yHzYaFtW" comment="BCM-mode GPIO pin to activate the air piston. Setting this pin to be high will press the &quot;Take Measurement&quot; button on the Disco. Setting this pin to be low will retract the piston to release the button. " initialValue="25" name="PISTON"/>
<UML:Attribute visibility="private" isSpecification="false" xmi.id="u04xfse750aW6" type="uC8n0yHzYaFtW" comment="BCM-mode GPIO pin for PWM control." initialValue="12" name="PWM"/>
<UML:Attribute visibility="private" isSpecification="false" xmi.id="uRNXMUhfRINIT" type="uC8n0yHzYaFtW" comment="BCM-mode GPIO pin for the physical run/pause switch on the fixture. If this pin is low, the test is running. If this pin is high, the test must be stopped." initialValue="10" name="RUN_SWITCH"/>
<UML:Attribute visibility="private" isSpecification="false" xmi.id="uwU3hjHwmL2Wh" type="uC8n0yHzYaFtW" comment="BCM-mode GPIO pin for the upper limit switch. If this pin reads high, the limit has been reached. Otherwise, this pin should read as low." initialValue="23" name="TOP_LIMIT"/>
<UML:Attribute visibility="private" isSpecification="false" xmi.id="u9QQxhPVspW9l" type="uC8n0yHzYaFtW" comment="BCM-mode GPIO pin for the lower limit switch. If this pin reads high, the limit has been reached. Otherwise, this pin should read low." initialValue="24" name="BOT_LIMIT"/>
<UML:Operation visibility="public" isSpecification="false" isQuery="false" isAbstract="false" isLeaf="false" ownerScope="classifier" isRoot="false" xmi.id="u0EBanNhgMx7X" comment="Initialises the Raspberry Pi GPIO library, and creates a Pi object.&#xa;Defaults all outputs, silences GPIO warnings." isOverride="false" name="init_hw" isInline="false" isVirtual="false">
<UML:BehavioralFeature.parameter>
<UML:Parameter kind="return" xmi.id="" type="uQ6I6JzsO2HGl"/>
</UML:BehavioralFeature.parameter>
</UML:Operation>
<UML:Operation visibility="public" isSpecification="false" isQuery="false" isAbstract="false" isLeaf="false" ownerScope="classifier" isRoot="false" xmi.id="uzCdyUze9yX4J" comment="Resets all GPIO to 0, calls GPIO cleanup, and calls pi.stop()" isOverride="false" name="cleanup" isInline="false" isVirtual="false">
<UML:BehavioralFeature.parameter>
<UML:Parameter visibility="private" isSpecification="false" xmi.id="ubju6uW2Sl14R" type="uQ6I6JzsO2HGl" value="" comment="PiGPIO object created by init_hw()" name="pi"/>
</UML:BehavioralFeature.parameter>
</UML:Operation>
<UML:Operation visibility="private" isSpecification="false" isQuery="false" isAbstract="false" isLeaf="false" ownerScope="classifier" isRoot="false" xmi.id="uxtY80lwBi7zq" comment="Sends the moving part of the fixture to the top or the bottom limit switch. If the limit switch is not pressed, the flow will eventualy timing out, before printing an error message and returning False. Otherwise, will return True." isOverride="false" name="goto_limit" isInline="false" isVirtual="false">
<UML:BehavioralFeature.parameter>
<UML:Parameter kind="return" xmi.id="uhSZKJeWEUGYw" type="uzncWu1t5XAqV"/>
<UML:Parameter visibility="private" isSpecification="false" xmi.id="uhkrB26QfOYQo" type="uC8n0yHzYaFtW" value="" comment="BCM-mode GPIO pin for the limit switch to listen for." name="limitswitch"/>
<UML:Parameter visibility="private" isSpecification="false" xmi.id="uZ7Dp9mRgtxJk" type="uC8n0yHzYaFtW" value="TIME_OUT" comment="Amount of seconds until the program will time-out." name="timeout"/>
</UML:BehavioralFeature.parameter>
</UML:Operation>
<UML:Operation visibility="public" isSpecification="false" isQuery="false" isAbstract="false" isLeaf="false" ownerScope="classifier" isRoot="false" xmi.id="uhMBGrq7UyGN8" comment="Wrapper for goto_limit() that sends the fixture to the top limit switch" isOverride="false" name="goto_top_limit" isInline="false" isVirtual="false">
<UML:BehavioralFeature.parameter>
<UML:Parameter kind="return" xmi.id="u2nyQ098UhUAY" type="uzncWu1t5XAqV"/>
<UML:Parameter visibility="private" isSpecification="false" xmi.id="uzF5yGXNWVIKL" type="uC8n0yHzYaFtW" value="TIME_OUT" comment="Number of seconds until the program should give up." name="timeout"/>
</UML:BehavioralFeature.parameter>
</UML:Operation>
<UML:Operation visibility="public" isSpecification="false" isQuery="false" isAbstract="false" isLeaf="false" ownerScope="classifier" isRoot="false" xmi.id="uQPa9LvXEplCu" comment="Wrapper for goto_limit() that sends the fixture to the bottom limit." isOverride="false" name="goto_bot_limit" isInline="false" isVirtual="false">
<UML:BehavioralFeature.parameter>
<UML:Parameter kind="return" xmi.id="uedNAve4Pqt6F" type="uzncWu1t5XAqV"/>
<UML:Parameter visibility="private" isSpecification="false" xmi.id="u4hmsBEjycSaq" type="uC8n0yHzYaFtW" value="TIME_OUT" comment="Amount of seconds before the fixture should give up." name="timeout"/>
</UML:BehavioralFeature.parameter>
</UML:Operation>
<UML:Operation visibility="public" isSpecification="false" isQuery="false" isAbstract="false" isLeaf="false" ownerScope="classifier" isRoot="false" xmi.id="u2UVDXa9OTsSR" comment="Extends compressed air piston for 1 second to press temperature button, then retracts the piston." isOverride="false" name="press_temp_btn" isInline="false" isVirtual="false"/>
<UML:Operation visibility="public" isSpecification="false" isQuery="false" isAbstract="false" isLeaf="false" ownerScope="classifier" isRoot="false" xmi.id="uKEDftAItizrV" comment="If the run switch is not active when this function is called, program flow will be held here until it becomes active." isOverride="false" name="check_pause" isInline="false" isVirtual="false"/>
<UML:Operation visibility="public" isSpecification="false" isQuery="false" isAbstract="false" isLeaf="false" ownerScope="classifier" isRoot="false" xmi.id="ui70uJ6muM7Xa" comment="Runs a simple test for the motor and piston.&#xa;&#xa;Moves the motor to the upper limit, presses the button on the Disco, moves the motor to the lower limit, presses the Disco button again, then moves the motor back to the upper limit, before running cleanup." isOverride="false" name="test_hw" isInline="false" isVirtual="false"/>
</UML:Classifier.feature>
</UML:Class>
<UML:Class visibility="public" isSpecification="false" namespace="Logical_View" isAbstract="false" isLeaf="false" isRoot="false" xmi.id="u6VqpQtja46wn" comment="Clock for traking the speed of some video feed in frames per second. The tick method should be called in a loop every time a frame is obtained from the video feed. The FPS can then be reported.&#xa;&#xa;Currently within camera_tools.py" name="FPSClock">
<UML:Classifier.feature>
<UML:Attribute visibility="public" isSpecification="false" xmi.id="u4WUp2PwsYM4i" type="ut3U2TtHTDMqm" comment="timestamp of when the instance of FPSClock was instantiated" name="start_time"/>
<UML:Attribute visibility="public" isSpecification="false" xmi.id="udBKRc4AmGjrD" type="ut3U2TtHTDMqm" comment="The amount of ticks that have happened in total" name="current_tick"/>
<UML:Attribute visibility="public" isSpecification="false" xmi.id="usGshqCwmzGc4" type="ut3U2TtHTDMqm" comment="timestamp of last tick (I think?)" name="last_tick"/>
<UML:Attribute visibility="private" isSpecification="false" xmi.id="uqsXpacajVP7j" type="urdHVFlCDEbzy" comment="Stores 5 tick times, is updated every time the clock is ticked. The average of this list is used for FPS reporting." name="tick_times"/>
<UML:Operation visibility="private" isSpecification="false" isQuery="false" isAbstract="false" isLeaf="false" isRoot="false" xmi.id="ufEvOSrA0kcSt" comment="Makes sure that the tick times array stays at length 5" isOverride="false" name="append_tick_time" isInline="false" isVirtual="false"/>
<UML:Operation visibility="public" isSpecification="false" isQuery="false" isAbstract="false" isLeaf="false" isRoot="false" xmi.id="uP33bLmUpvU3x" comment="Gets the total time the clock has been running (current time - start time)" isOverride="false" name="runtime" isInline="false" isVirtual="false">
<UML:BehavioralFeature.parameter>
<UML:Parameter kind="return" xmi.id="unpbiRFCLtHV6" type="ut3U2TtHTDMqm"/>
</UML:BehavioralFeature.parameter>
</UML:Operation>
<UML:Operation visibility="public" isSpecification="false" isQuery="false" isAbstract="false" isLeaf="false" isRoot="false" xmi.id="uyztga7pvel5D" comment="Reports the current FPS of the clock" isOverride="false" name="fps" isInline="false" isVirtual="false">
<UML:BehavioralFeature.parameter>
<UML:Parameter kind="return" xmi.id="u5di2q42Gtf1v" type="ut3U2TtHTDMqm"/>
</UML:BehavioralFeature.parameter>
</UML:Operation>
</UML:Classifier.feature>
</UML:Class>
<UML:Class visibility="public" isSpecification="false" namespace="Logical_View" isAbstract="false" isLeaf="false" isRoot="false" xmi.id="uThfpCkW5KNLv" comment="CLI implementation. Rudamentary; allows for change in PWM frequency, spawns the GUI" name="application">
<UML:Classifier.feature>
<UML:Attribute visibility="public" isSpecification="false" xmi.id="uw6PICFVwOCba" type="uzncWu1t5XAqV" comment="Whether to check if the user's PWM frequency is correct before starting AOL tests" initialValue="False" name="DOUBLE_CHECK"/>
<UML:Operation visibility="public" isSpecification="false" isQuery="false" isAbstract="false" isLeaf="false" isRoot="false" xmi.id="uAvdIrTdIHqSR" comment="Outputs the current PWM frequency, asks the user to input a new frequency value, then sets the PWM frequency to the new user-defined value" isOverride="false" name="get_new_freq" isInline="false" isVirtual="false"/>
<UML:Operation visibility="public" isSpecification="false" isQuery="false" isAbstract="false" isLeaf="false" isRoot="false" xmi.id="uMaStZQf88d7V" comment="Checks whether the user is alright with the current PWM frequency. Does nothing if DOUBLE_CHECK is False" isOverride="false" name="freq_query" isInline="false" isVirtual="false"/>
<UML:Operation visibility="public" isSpecification="false" isQuery="false" isAbstract="false" isLeaf="false" ownerScope="classifier" isRoot="false" xmi.id="uFB9wjh3mxa6V" comment="This program is intended to be run first, and spawns a Qt GUI upon the correct input.&#xa;&#xa;Prompts the user for a selectio, then runs the selected program until the user quits. " isOverride="false" name="main" isInline="false" isVirtual="false"/>
</UML:Classifier.feature>
</UML:Class>
<UML:Dependency visibility="public" isSpecification="false" namespace="Logical_View" supplier="uoU85LGuFdMDB" xmi.id="udaV98vJAtD5V" client="uThfpCkW5KNLv" name=""/>
<UML:Class visibility="public" isSpecification="false" namespace="Logical_View" isAbstract="false" isLeaf="false" isRoot="false" xmi.id="u3PKuOJQ3ZHmI" comment="MVC Model for the GUI. Defines all available interactions with underlying classes and objects." name="AOLFixture">
<UML:Classifier.feature>
<UML:Attribute visibility="public" isSpecification="false" ownerScope="classifier" xmi.id="u6fxkTP89Z1qe" type="uC8n0yHzYaFtW" comment="Width, in pixels, of the raw frames captured by the camera. " initialValue="800" name="FRAME_WIDTH"/>
<UML:Attribute visibility="public" isSpecification="false" ownerScope="classifier" xmi.id="upZaWekqlJGOu" type="uC8n0yHzYaFtW" comment="Height, in pixels, of the raw frames captured by the camera." initialValue="600" name="FRAME_HEIGHT"/>
<UML:Attribute visibility="public" isSpecification="false" ownerScope="classifier" xmi.id="uyapd5AklqW2M" type="ufgglRaUHqAMn" comment="Default video port for Camera 1" initialValue="&quot;/dev/video0&quot;" name="DEFAULT_CAM1_PORT"/>
<UML:Attribute visibility="public" isSpecification="false" ownerScope="classifier" xmi.id="uVSsIBojVxely" type="ufgglRaUHqAMn" comment="Default video port for camera 2" initialValue="&quot;/dev/video2&quot;" name="DEFAULT_CAM2_PORT"/>
<UML:Attribute visibility="public" isSpecification="false" ownerScope="classifier" xmi.id="uoLKqxEi69MUl" type="ufgglRaUHqAMn" comment="What to set the OCR reading to when an image from a camera is invalid" initialValue="&quot;CAMERA ERROR&quot;" name="CAM_ERROR_MSG"/>
<UML:Attribute visibility="private" isSpecification="false" xmi.id="uT8SNBGCApzWW" type="urdHVFlCDEbzy" comment="List of observers of this object affected by &quot;alert_observers()&quot;" name="observers"/>
<UML:Attribute visibility="public" isSpecification="false" xmi.id="u8MCZU4xbMiEg" type="uR5ObfNSeeXhB" comment="Device config for the fixture" name="cfg"/>
<UML:Attribute visibility="public" isSpecification="false" xmi.id="ufYv515nwSPqj" type="ufgglRaUHqAMn" comment="Communication &quot;&quot;&quot;bus&quot;&quot;&quot; between observers and this object" initialValue="&quot;&quot;" name="output_buff"/>
<UML:Attribute visibility="public" isSpecification="false" xmi.id="uaUz0wgB6JyLj" type="ufgglRaUHqAMn" comment="Name of the log file. Empty string if not in use" initialValue="&quot;&quot;" name="log_name"/>
<UML:Attribute visibility="public" isSpecification="false" xmi.id="uQktcNU0aviX8" type="ufgglRaUHqAMn" comment="Location to save the images to, if using logging." initialValue="&quot;&quot;" name="img_dir"/>
<UML:Attribute visibility="public" isSpecification="false" xmi.id="uymjTPSDmdslG" type="uzncWu1t5XAqV" comment="Whether or not an Accuracy Over Life test is currently being run." initialValue="false" name="aol_running"/>
<UML:Attribute visibility="public" isSpecification="false" xmi.id="uwUwxWUudCOHB" type="uC8n0yHzYaFtW" comment="Number of cycles being performed in this Accuracy Over Life test" initialValue="10000" name="num_cycles"/>
<UML:Attribute visibility="private" isSpecification="false" xmi.id="uRi1y0XyJalyj" type="uC8n0yHzYaFtW" comment="Current cycle number" initialValue="0" name="cycle_num"/>
<UML:Attribute visibility="public" isSpecification="false" xmi.id="ufIN4B2QLPgEQ" type="uDw2wLV7OL4hx" comment="OpenCV VideoCapture object for Camera2" name="cam1"/>
<UML:Attribute visibility="public" isSpecification="false" xmi.id="uL2g1QxGDWG8P" type="uDw2wLV7OL4hx" comment="OpenCV VideoCapture object for Camera2" name="cam2"/>
<UML:Attribute visibility="public" isSpecification="false" xmi.id="uNQiElSTPK1AA" type="uQ6I6JzsO2HGl" comment="Pi object for interacting with GPIO" name="pi"/>
<UML:Attribute visibility="public" isSpecification="false" xmi.id="u0Xj0X088euUT" type="ue6uiThNgNDFB" comment="Raw values for Image1" name="img1"/>
<UML:Attribute visibility="public" isSpecification="false" xmi.id="ut9nKlwYYnVoi" type="ue6uiThNgNDFB" comment="Raw values for Image2" name="img2"/>
<UML:Attribute visibility="public" isSpecification="false" xmi.id="uA0ZTyryE5xWB" type="ufgglRaUHqAMn" comment="Path where img1 is being saved" initialValue="&quot;&quot;" name="img1_path"/>
<UML:Attribute visibility="public" isSpecification="false" xmi.id="uu9ijKRtgAZ41" type="ufgglRaUHqAMn" comment="Path where img2 is saved" initialValue="&quot;&quot;" name="img2_path"/>
<UML:Attribute visibility="public" isSpecification="false" xmi.id="uGDIcSUE3EGw1" type="ufgglRaUHqAMn" comment="Text read from img1" initialValue="&quot;&quot;" name="text1"/>
<UML:Attribute visibility="public" isSpecification="false" xmi.id="uDb3JwPxTrhjI" type="ufgglRaUHqAMn" comment="Text read from img2" initialValue="&quot;&quot;" name="text2"/>
<UML:Attribute visibility="private" isSpecification="false" xmi.id="udPNNn2PcNrHC" type="uzwE2u8G0m86m" name="new_attribute"/>
<UML:Operation visibility="private" isSpecification="false" isQuery="false" isAbstract="false" isLeaf="false" isRoot="false" xmi.id="u1XeTdWi0QBh4" comment="Resets attributes associated with AOL. &#xa;&#xa;aol_running is set to False. &#xa;cam1, cam2, pi, img1, and img2 are set to null" isOverride="false" name="reset_aol_attributes" isInline="false" isVirtual="false"/>
<UML:Operation visibility="private" isSpecification="false" isQuery="false" isAbstract="false" isLeaf="false" isRoot="false" xmi.id="uiXEv7E9KGfsR" comment="Loads initial config, gives it sections Cam1 and Cam2, with default values if it has no sections. DEFAULT_CAM1_PORT and DEFAULT_CAM2_PORT are assigned to the PORT properties of Cam1 and Cam2, respectively, if those sections are created by this function." isOverride="false" name="load_initial_cfg" isInline="false" isVirtual="false"/>
<UML:Operation visibility="public" isSpecification="false" isQuery="false" isAbstract="false" isLeaf="false" isRoot="false" xmi.id="uO2fh3ZIpaQ0Q" comment="Add observer to the list of observers" isOverride="false" name="add_observer" isInline="false" isVirtual="false">
<UML:BehavioralFeature.parameter>
<UML:Parameter visibility="private" isSpecification="false" xmi.id="uLp6IEZUiXnCG" type="uwl3mL4D79Yo7" value="" comment="New Observer " name="observer"/>
</UML:BehavioralFeature.parameter>
</UML:Operation>
<UML:Operation visibility="public" isSpecification="false" isQuery="false" isAbstract="false" isLeaf="false" isRoot="false" xmi.id="upkwhWC3xlCWC" comment="Removes the given observer from the observer list" isOverride="false" name="remove_observer" isInline="false" isVirtual="false">
<UML:BehavioralFeature.parameter>
<UML:Parameter visibility="private" isSpecification="false" xmi.id="uLbTqV9HddRRm" type="uwl3mL4D79Yo7" value="" name="observer"/>
</UML:BehavioralFeature.parameter>
</UML:Operation>
<UML:Operation visibility="public" isSpecification="false" isQuery="false" isAbstract="false" isLeaf="false" isRoot="false" xmi.id="u7NJmYxPdLR2E" comment="Sets the output buffer to the given message, calls the update method on all available observers, then resets the output buffer to an empty string" isOverride="false" name="alert_observers" isInline="false" isVirtual="false"/>
<UML:Operation visibility="private" isSpecification="false" isQuery="false" isAbstract="false" isLeaf="false" isRoot="false" xmi.id="ueC1huFz5YPpg" comment="Helper method for creating the OpenCV VideoCapture references. &#xa;&#xa;Assumes this.cfg has sections Cam1 and Cam2" isOverride="false" name="prepare_cams" isInline="false" isVirtual="false"/>
<UML:Operation visibility="private" isSpecification="false" isQuery="false" isAbstract="false" isLeaf="false" isRoot="false" xmi.id="uO5FndUBgdMJz" comment="Helper method for initialising test run logging using log_tools.init_logs() and storing the returned log name and image directory name in this object's log_name and img_dir attributes" isOverride="false" name="prepare_logging" isInline="false" isVirtual="false"/>
<UML:Operation visibility="private" isSpecification="false" isQuery="false" isAbstract="false" isLeaf="false" isRoot="false" xmi.id="uUPdS1ZrMGgcF" comment="Helper method for preparing the fixture hardware using the fixture_gpio module and saving a reference to the Pi object created, so it can be destroyed later" isOverride="false" name="prepare_hw" isInline="false" isVirtual="false"/>
<UML:Operation visibility="private" isSpecification="false" isQuery="false" isAbstract="false" isLeaf="false" isRoot="false" xmi.id="u0Lt9TbmnJ6LX" comment="Helper method for recovering the fixture hardware if it times out trying to move to a limit switch If fixture hardware times out inside this function, this.stop() is called." isOverride="false" name="recover_hw" isInline="false" isVirtual="false">
<UML:BehavioralFeature.parameter>
<UML:Parameter visibility="private" isSpecification="false" xmi.id="uFgHDY4LVxA7y" type="uzncWu1t5XAqV" value="" comment="True to recover by moving the fixture to the top limit switc. False to recover by moving the fixture to the bottom limit switch." name="top"/>
</UML:BehavioralFeature.parameter>
</UML:Operation>
<UML:Operation visibility="private" isSpecification="false" isQuery="false" isAbstract="false" isLeaf="false" isRoot="false" xmi.id="uOGEHt4i016lY" comment="Helper method for taking a picture on a given camera. The picture is cropped, thresholded, and composited all at once using camera_tools.compose.img(). The config properties in the given config section are used in this process." isOverride="false" name="take_picture" isInline="false" isVirtual="false">
<UML:BehavioralFeature.parameter>
<UML:Parameter kind="return" xmi.id="uivcvkrn1v6h2" type="ue6uiThNgNDFB"/>
<UML:Parameter visibility="private" isSpecification="false" xmi.id="ufD4IJLk5pRPM" type="uDw2wLV7OL4hx" value="" comment="Video feed to take a picture with" name="cam"/>
<UML:Parameter visibility="private" isSpecification="false" xmi.id="uU2efFPesmICa" type="ufgglRaUHqAMn" value="" comment="Name of the config section associated with the given camera" name="cfg_sec_name"/>
</UML:BehavioralFeature.parameter>
</UML:Operation>
<UML:Operation visibility="private" isSpecification="false" isQuery="false" isAbstract="false" isLeaf="false" isRoot="false" xmi.id="uLePJCLiyq259" comment="Helper function for saving this.img1 and this.img2 in the images directory for this test run. Only saves an image if it is not null. If an image is null, an empty string is returned for that image's file path." isOverride="false" name="save_imgs" isInline="false" isVirtual="false">
<UML:BehavioralFeature.parameter>
<UML:Parameter kind="return" xmi.id="uIecppGbpaR7Q" type="uSN9tVhGt4JeL"/>
</UML:BehavioralFeature.parameter>
</UML:Operation>
<UML:Operation visibility="private" isSpecification="false" isQuery="false" isAbstract="false" isLeaf="false" isRoot="false" xmi.id="uyQDSKZoMq9BF" comment="Run a single accuracy over life test cycle. Assumes this.cfg has sections &quot;Cam1&quot; and &quot;Cam2&quot;" isOverride="false" name="test_cycle" isInline="false" isVirtual="false">
<UML:BehavioralFeature.parameter>
<UML:Parameter kind="return" xmi.id="ubYKpBNZA5vvW" type="uSN9tVhGt4JeL"/>
</UML:BehavioralFeature.parameter>
</UML:Operation>
<UML:Operation visibility="public" isSpecification="false" isQuery="false" isAbstract="false" isLeaf="false" isRoot="false" xmi.id="u2xVDrZOlSOdH" comment="Runs a full accuracy over life test on this fixture for the given number of cycles. Initialises the test by calling prepare_cams(), prepare_logging(), and prepare_hw(), then setting this.num_cycles to the given number of cycles. Between each test cycle, the results returned by test_cycle() are written to the log file for this run and this.cycle_num is incremented. When testing is finished, or stopped, cleanup() is called. The test is stopped early if this.aol_running becomes False. This method has no effect if this.aol_running is True when it is called. (This is a soft check to stop the same instance of AOLFixture from running multiple tests simultaneously.)" isOverride="false" name="run" isInline="false" isVirtual="false">
<UML:BehavioralFeature.parameter>
<UML:Parameter visibility="private" isSpecification="false" xmi.id="uh3jOokmtdneW" type="uC8n0yHzYaFtW" value="" comment="Number of test cycles to run" name="num_cycles"/>
</UML:BehavioralFeature.parameter>
</UML:Operation>
<UML:Operation visibility="public" isSpecification="false" isQuery="false" isAbstract="false" isLeaf="false" isRoot="false" xmi.id="uluEZIogNmfGj" comment="Stops the curently running accuracy life test CLEANLY by setting this.aol_running to False. If this.aol_running is False when this method is called, it has no effect." isOverride="false" name="stop" isInline="false" isVirtual="false"/>
<UML:Operation visibility="public" isSpecification="false" isQuery="false" isAbstract="false" isLeaf="false" isRoot="false" xmi.id="uLDln74tq9szY" comment="Cleans up the fixture hardware, releases the video streams, and calls reset_aol_attributes() to prepare or a new AOL test." isOverride="false" name="cleanup" isInline="false" isVirtual="false"/>
<UML:Operation visibility="public" isSpecification="false" isQuery="false" isAbstract="false" isLeaf="false" isRoot="false" xmi.id="uPdYwEtgwUr7M" comment="Getter for the difference between the number of AOL test cycles being performed, and the current number." isOverride="false" name="get_cycles_left" isInline="false" isVirtual="false">
<UML:BehavioralFeature.parameter>
<UML:Parameter kind="return" xmi.id="unSIfcgZGg1Me" type="uC8n0yHzYaFtW"/>
</UML:BehavioralFeature.parameter>
</UML:Operation>
</UML:Classifier.feature>
</UML:Class>
<UML:Class visibility="public" isSpecification="false" namespace="Logical_View" isAbstract="false" isLeaf="false" isRoot="false" xmi.id="uGAAftKX0LKPe" comment="TODO" name="gui">
<UML:Classifier.feature>
<UML:Operation visibility="public" isSpecification="false" isQuery="false" isAbstract="false" isLeaf="false" isRoot="false" xmi.id="uUBAUdS6srw6D" comment="Helper function for converting an arbitrary string into a float and catching the potential errors associated.&#xa;&#xa;Currently returns 1 if text is not a number. Should be modified to be -1, if possible" isOverride="false" name="text_to_valid_float" isInline="false" isVirtual="false">
<UML:BehavioralFeature.parameter>
<UML:Parameter kind="return" xmi.id="uW22GbgzqLcQ6" type="ut3U2TtHTDMqm"/>
<UML:Parameter visibility="private" isSpecification="false" xmi.id="u2NJUmYxD1HRR" type="ufgglRaUHqAMn" value="" comment="String to be converted to float" name="text"/>
</UML:BehavioralFeature.parameter>
</UML:Operation>
<UML:Operation visibility="public" isSpecification="false" isQuery="false" isAbstract="false" isLeaf="false" isRoot="false" xmi.id="uZaEMGpppzuKF" comment="Helper function for converting an arbitrary string into an int and catching the potential errors associated.&#xa;&#xa;Currently returns 1 if text is not a number. Should be changed to -1 if possible." isOverride="false" name="text_to_valid_int" isInline="false" isVirtual="false">
<UML:BehavioralFeature.parameter>
<UML:Parameter kind="return" xmi.id="uQklWmIwqowQq" type="uC8n0yHzYaFtW"/>
<UML:Parameter visibility="private" isSpecification="false" xmi.id="uMyZonuw0HcTR" type="ufgglRaUHqAMn" value="" comment="String to be converted" name="text"/>
</UML:BehavioralFeature.parameter>
</UML:Operation>
<UML:Operation visibility="public" isSpecification="false" isQuery="false" isAbstract="false" isLeaf="false" isRoot="false" xmi.id="uqIrOThJN3Ivp" comment="Attempts to open a camera preview window, using the video device on the given port. Gets a composite image using camera_tools.compose_img() and displays it if possible. If not, a warning is printed to stderr and the function does nothing." isOverride="false" name="preview" isInline="false" isVirtual="false">
<UML:BehavioralFeature.parameter>
<UML:Parameter visibility="private" isSpecification="false" xmi.id="ukljsrvFnTYYY" type="ufgglRaUHqAMn" value="&quot;/dev/video0&quot;" comment="Video port of the camera" name="port"/>
<UML:Parameter visibility="private" isSpecification="false" xmi.id="uRFFY6tK0mlac" type="uzncWu1t5XAqV" value="" comment="Whether or not to process the preview image through a binary threshold, gamma adjustment, and composition" name="threshold"/>
<UML:Parameter visibility="private" isSpecification="false" xmi.id="uxkLlSuhdtGbT" type="ut3U2TtHTDMqm" value="" comment="gamma adjustment value (Only used if threshold is True)" name="gamma"/>
<UML:Parameter visibility="private" isSpecification="false" xmi.id="uS9hUZ8MQXGr3" type="uC8n0yHzYaFtW" value="" comment="number of frames to compose together (Only used if threshold is true)" name="c_frames"/>
<UML:Parameter visibility="private" isSpecification="false" xmi.id="uiwS62ggqIdD8" type="uzncWu1t5XAqV" value="" comment="Whether or not to crop the given image" name="crop"/>
<UML:Parameter visibility="private" isSpecification="false" xmi.id="uFS8Sc3iuzZAn" type="uC8n0yHzYaFtW" value="" comment="x-coordinate of the crop (Only used if crop is True)" name="x"/>
<UML:Parameter visibility="private" isSpecification="false" xmi.id="udupIuFu8FGEz" type="uC8n0yHzYaFtW" value="" comment="y-coordinate of crop (only used if crop is True)" name="y"/>
<UML:Parameter visibility="private" isSpecification="false" xmi.id="u7DY0winTafBr" type="uC8n0yHzYaFtW" value="" comment="width, in pixels, of the cropped image (Only used if crop is True)" name="w"/>
<UML:Parameter visibility="private" isSpecification="false" xmi.id="uGdOPE5tsH532" type="uC8n0yHzYaFtW" value="" comment="height, in pixels, of the cropped image. (only used if crop is True)" name="h"/>
</UML:BehavioralFeature.parameter>
</UML:Operation>
</UML:Classifier.feature>
</UML:Class>
<UML:Dependency visibility="public" isSpecification="false" namespace="Logical_View" supplier="uGAAftKX0LKPe" xmi.id="uy1xEgXwf84zo" client="uThfpCkW5KNLv" name=""/>
<UML:Dependency visibility="public" isSpecification="false" namespace="Logical_View" supplier="u3PKuOJQ3ZHmI" xmi.id="ue5VpiyFv6Lgr" client="uGAAftKX0LKPe" name=""/>
<UML:Class visibility="public" isSpecification="false" namespace="Logical_View" isAbstract="false" isLeaf="false" isRoot="false" xmi.id="uR5ObfNSeeXhB" comment="Class used for interacting with settings (saving, loading, reading, and writing)." name="DeviceConfig">
<UML:Classifier.feature>
<UML:Attribute visibility="private" isSpecification="false" ownerScope="classifier" xmi.id="uLZD8gmVseX6H" type="ufgglRaUHqAMn" comment="PORT Key for DEFAULT_CONFIG map" initialValue="&quot;port&quot;" name="PORT"/>
<UML:Attribute visibility="public" isSpecification="false" ownerScope="classifier" xmi.id="urtrPGD8N67ak" type="ufgglRaUHqAMn" comment="ACTIVE key for DEFAULT_CONFIG map" initialValue="&quot;active&quot;" name="ACTIVE"/>
<UML:Attribute visibility="public" isSpecification="false" ownerScope="classifier" xmi.id="usgU8DKlARM7s" type="ufgglRaUHqAMn" comment="CROP_X key for DEFAULT_CONFIG map" initialValue="&quot;cropx&quot;" name="CROP_X"/>
<UML:Attribute visibility="public" isSpecification="false" ownerScope="classifier" xmi.id="uMboyjzkx7nU5" type="ufgglRaUHqAMn" comment="CROP_Y key for DEFAULT_CONFIG map" initialValue="&quot;cropy&quot;" name="CROP_Y"/>
<UML:Attribute visibility="public" isSpecification="false" ownerScope="classifier" xmi.id="uslwnDGlFhEKl" type="ufgglRaUHqAMn" comment="CROP_W key for DEFAULT_CONFIG map" initialValue="&quot;cropw&quot;" name="CROP_W"/>
<UML:Attribute visibility="public" isSpecification="false" ownerScope="classifier" xmi.id="uWE1lJn5ztJt4" type="ufgglRaUHqAMn" comment="CROP_H key for DEFAULT_CONFIG map" initialValue="&quot;croph&quot;" name="CROP_H"/>
<UML:Attribute visibility="public" isSpecification="false" ownerScope="classifier" xmi.id="u5DfWhjMibNqp" type="ufgglRaUHqAMn" comment="GAMMA key for DEFAULT_CONFIG map" initialValue="&quot;gamma&quot;" name="GAMMA"/>
<UML:Attribute visibility="public" isSpecification="false" ownerScope="classifier" xmi.id="uwm6wS4amN83t" type="ufgglRaUHqAMn" comment="C_FRAMES key for DEFAULT_CONFIG map" initialValue="&quot;compositeframes&quot;" name="C_FRAMES"/>
<UML:Attribute visibility="public" isSpecification="false" ownerScope="classifier" xmi.id="uD9jHFWDVmkVF" type="ufgglRaUHqAMn" comment="PRIME key for DEFAULT_CONFIG map" initialValue="&quot;prime&quot;" name="PRIME"/>
<UML:Attribute visibility="public" isSpecification="false" ownerScope="classifier" xmi.id="uyCGecgUq18Mv" type="uSN9tVhGt4JeL" comment="Array of the name of all properties stored in the config&#xa;&#xa;(Could probably be rewritten as an enum)" initialValue="[PORT, ACTIVE, CROP_X, CROP_Y, CROP_W, CROP_H, GAMMA, C_FRAMES, PRIME]" name="PROPERTY_NAMES"/>
<UML:Attribute visibility="public" isSpecification="false" xmi.id="uVyfgg9vCFyLF" type="unEKbNBpRDYxe" comment="Map of all config options&#xa;Default options are based on private variables&#xa;&#xa;Contains:&#xa;- PORT&#xa;- ACTIVE&#xa;- CROP_X&#xa;- CROP_Y&#xa;- CROP_W&#xa;- CROP_H&#xa;- GAMMA&#xa;- C_FRAMES&#xa;- PRIME" name="DEFAULT_CONFIG"/>
<UML:Attribute visibility="public" isSpecification="false" ownerScope="classifier" xmi.id="ufH4qMUyirg5i" type="ufgglRaUHqAMn" comment="Default filepath for config file" initialValue="&quot;config.cfg&quot;" name="DEFAULT_FILEPATH"/>
<UML:Attribute visibility="public" isSpecification="false" xmi.id="upDIZFxX7bZ6O" type="ufgglRaUHqAMn" comment="The current file path for the config file" initialValue="DEFAULT_FILEPATH" name="filepath"/>
<UML:Attribute visibility="private" isSpecification="false" xmi.id="u6UhY8WirooGu" type="uCW0AMheY8JMc" comment="ConfigParser instance; used for easier parsing of config file." name="parser"/>
<UML:Attribute visibility="private" isSpecification="false" xmi.id="u2yY3Af7pGO0b" type="uC8n0yHzYaFtW" comment="Next section number. Stored for convenience (as far as I can tell)" initialValue="1" name="next_sec_num"/>
<UML:Operation visibility="private" isSpecification="false" isQuery="false" isAbstract="false" isLeaf="false" isRoot="false" xmi.id="ukY6qrpCL8Nlr" comment="Gets the next section name (used when creating new config sections)" isOverride="false" name="get_next_sec_name" isInline="false" isVirtual="false">
<UML:BehavioralFeature.parameter>
<UML:Parameter kind="return" xmi.id="uzRdJfBIgMDSk" type="ufgglRaUHqAMn"/>
</UML:BehavioralFeature.parameter>
</UML:Operation>
<UML:Operation visibility="public" isSpecification="false" isQuery="false" isAbstract="false" isLeaf="false" isRoot="false" xmi.id="up4FwTAhBBJRk" comment="Sets the properties in every section of the config to their default values" isOverride="false" name="set_to_defaults" isInline="false" isVirtual="false"/>
<UML:Operation visibility="public" isSpecification="false" isQuery="false" isAbstract="false" isLeaf="false" isRoot="false" xmi.id="uxEFottbVdn4G" comment="Save the current config options to a file" isOverride="false" name="save_config" isInline="false" isVirtual="false"/>
<UML:Operation visibility="public" isSpecification="false" isQuery="false" isAbstract="false" isLeaf="false" isRoot="false" xmi.id="uMpUhKnowbroP" comment="Load the config from file. If this config's file cannot be found, a default config is generated, and saved at the default file path" isOverride="false" name="load_config" isInline="false" isVirtual="false"/>
<UML:Operation visibility="private" isSpecification="false" isQuery="false" isAbstract="false" isLeaf="false" isRoot="false" xmi.id="uiAextWuFOiac" comment="Helper function for converting a config property value (which by default is a string) into an int. This function throws a ValueError if the given property does not have an integer value.&#x9;" isOverride="false" name="get_int_value" isInline="false" isVirtual="false">
<UML:BehavioralFeature.parameter>
<UML:Parameter kind="return" xmi.id="urBAJD2mv1RnB" type="uC8n0yHzYaFtW"/>
<UML:Parameter visibility="private" isSpecification="false" xmi.id="u0v8Lv8D13JKR" type="ufgglRaUHqAMn" value="" comment="Config section name" name="sec_name"/>
<UML:Parameter visibility="private" isSpecification="false" xmi.id="ulxYVGRKvodTQ" type="ufgglRaUHqAMn" value="" comment="Config's property name" name="property"/>
</UML:BehavioralFeature.parameter>
</UML:Operation>
<UML:Operation visibility="private" isSpecification="false" isQuery="false" isAbstract="false" isLeaf="false" isRoot="false" xmi.id="u2NFAHYdxh8lI" comment="Helper function which converts a config property value (which is, by default, a string) into a boolean." isOverride="false" name="get_bool_value" isInline="false" isVirtual="false">
<UML:BehavioralFeature.parameter>
<UML:Parameter kind="return" xmi.id="u5N9i36PcJzc9" type="uzncWu1t5XAqV"/>
<UML:Parameter visibility="private" isSpecification="false" xmi.id="uztsxeWSQiToV" type="ufgglRaUHqAMn" value="" comment="Config's section name" name="sec_name"/>
<UML:Parameter visibility="private" isSpecification="false" xmi.id="ubTiu9l65uBLz" type="ufgglRaUHqAMn" value="" comment="Config's property name" name="property"/>
</UML:BehavioralFeature.parameter>
</UML:Operation>
<UML:Operation visibility="public" isSpecification="false" isQuery="false" isAbstract="false" isLeaf="false" isRoot="false" xmi.id="uI1i2o8Gc0RLs" comment="Helper function that returns the PORT property in the input section" isOverride="false" name="get_port" isInline="false" isVirtual="false">
<UML:BehavioralFeature.parameter>
<UML:Parameter kind="return" xmi.id="uW5CrqJhlQkc2" type="ufgglRaUHqAMn"/>
<UML:Parameter visibility="private" isSpecification="false" xmi.id="uRHgvkTatE7ye" type="ufgglRaUHqAMn" value="" comment="Config's section name" name="sec_name"/>
</UML:BehavioralFeature.parameter>
</UML:Operation>
<UML:Operation visibility="public" isSpecification="false" isQuery="false" isAbstract="false" isLeaf="false" isRoot="false" xmi.id="u7FWGOooMzqnV" comment="Helper function for getting the value of the ACTIVE property in the given section" isOverride="false" name="get_active" isInline="false" isVirtual="false">
<UML:BehavioralFeature.parameter>
<UML:Parameter kind="return" xmi.id="uuKULb5tXVE5I" type="uzncWu1t5XAqV"/>
<UML:Parameter visibility="private" isSpecification="false" xmi.id="uSJaFwy5jvx0j" type="uzncWu1t5XAqV" value="" comment="Config's section name" name="sec_name"/>
</UML:BehavioralFeature.parameter>
</UML:Operation>
<UML:Operation visibility="public" isSpecification="false" isQuery="false" isAbstract="false" isLeaf="false" isRoot="false" xmi.id="uxNf4PYxgZFeP" comment="Helper function for getting the value of the CROP_X property in the given section" isOverride="false" name="get_crop_x" isInline="false" isVirtual="false">
<UML:BehavioralFeature.parameter>
<UML:Parameter kind="return" xmi.id="ufYOH7OYUiplT" type="uC8n0yHzYaFtW"/>
<UML:Parameter visibility="private" isSpecification="false" xmi.id="umNLJiaD4kURJ" type="ufgglRaUHqAMn" value="" comment="Config's section name" name="sec_name"/>
</UML:BehavioralFeature.parameter>
</UML:Operation>
<UML:Operation visibility="public" isSpecification="false" isQuery="false" isAbstract="false" isLeaf="false" isRoot="false" xmi.id="uFBKNmVkJwXAg" comment="Helper function for getting the value of the CROP_Y property in the given section" isOverride="false" name="get_crop_y" isInline="false" isVirtual="false">
<UML:BehavioralFeature.parameter>
<UML:Parameter kind="return" xmi.id="u5GnnWmW1nfbZ" type="uC8n0yHzYaFtW"/>
<UML:Parameter visibility="private" isSpecification="false" xmi.id="u1t3oyebH33qg" type="ufgglRaUHqAMn" value="" comment="Config's section name" name="sec_name"/>
</UML:BehavioralFeature.parameter>
</UML:Operation>
<UML:Operation visibility="public" isSpecification="false" isQuery="false" isAbstract="false" isLeaf="false" isRoot="false" xmi.id="ufBtk9B5e6vcY" comment="Helper function for getting the value of the CROP_W property in the given section" isOverride="false" name="get_crop_w" isInline="false" isVirtual="false">
<UML:BehavioralFeature.parameter>
<UML:Parameter kind="return" xmi.id="uioARIH6LhmOm" type="uC8n0yHzYaFtW"/>
<UML:Parameter visibility="private" isSpecification="false" xmi.id="u89P3IAGcVrvI" type="ufgglRaUHqAMn" value="" comment="Config's section name" name="sec_name"/>
</UML:BehavioralFeature.parameter>
</UML:Operation>
<UML:Operation visibility="public" isSpecification="false" isQuery="false" isAbstract="false" isLeaf="false" isRoot="false" xmi.id="uh9lxiqqZvb4t" comment="Helper function for getting the value of CROP_H property in the given section" isOverride="false" name="get_crop_h" isInline="false" isVirtual="false">
<UML:BehavioralFeature.parameter>
<UML:Parameter kind="return" xmi.id="uB9FVYO8PGFlb" type="uC8n0yHzYaFtW"/>
<UML:Parameter visibility="private" isSpecification="false" xmi.id="udQAF2S332QtK" type="ufgglRaUHqAMn" value="" comment="Config's section name" name="sec_name"/>
</UML:BehavioralFeature.parameter>
</UML:Operation>
<UML:Operation visibility="public" isSpecification="false" isQuery="false" isAbstract="false" isLeaf="false" isRoot="false" xmi.id="uU4wEZvpnz3fQ" comment="Helper function for getting the value of the GAMMA property in the given section" isOverride="false" name="get_gamma" isInline="false" isVirtual="false">
<UML:BehavioralFeature.parameter>
<UML:Parameter kind="return" xmi.id="u49O6EReyo1t5" type="ut3U2TtHTDMqm"/>
<UML:Parameter visibility="private" isSpecification="false" xmi.id="uvaxKa9wOvgMH" type="ufgglRaUHqAMn" value="" comment="Config's section name" name="sec_name"/>
</UML:BehavioralFeature.parameter>
</UML:Operation>
<UML:Operation visibility="public" isSpecification="false" isQuery="false" isAbstract="false" isLeaf="false" isRoot="false" xmi.id="uf6RsnKhtZkhd" comment="Helper function for getting thte value of the C_FRAMES property in the given section" isOverride="false" name="get_c_frames" isInline="false" isVirtual="false">
<UML:BehavioralFeature.parameter>
<UML:Parameter kind="return" xmi.id="uV77J1dnfyf8a" type="uC8n0yHzYaFtW"/>
<UML:Parameter visibility="private" isSpecification="false" xmi.id="uOFF0Nzbudg4N" type="ufgglRaUHqAMn" value="" comment="Config's section name" name="sec_name"/>
</UML:BehavioralFeature.parameter>
</UML:Operation>
<UML:Operation visibility="public" isSpecification="false" isQuery="false" isAbstract="false" isLeaf="false" isRoot="false" xmi.id="uXvrVLeazI8eQ" comment="Helper function for getting the value of the PRIME property in the given section" isOverride="false" name="get_prime" isInline="false" isVirtual="false">
<UML:BehavioralFeature.parameter>
<UML:Parameter kind="return" xmi.id="uw6eHQK5mJE9I" type="uzncWu1t5XAqV"/>
<UML:Parameter visibility="private" isSpecification="false" xmi.id="uE4QWSDE5u86H" type="ufgglRaUHqAMn" value="" comment="Config's section name" name="sec_name"/>
</UML:BehavioralFeature.parameter>
</UML:Operation>
<UML:Operation visibility="public" isSpecification="false" isQuery="false" isAbstract="false" isLeaf="false" isRoot="false" xmi.id="uRKZ3442mgMnu" comment="Helper function for getting the value of the given property in the given section. Output will always be string, for safety. This function should be deprecated if possible." isOverride="false" name="get_item" isInline="false" isVirtual="false">
<UML:BehavioralFeature.parameter>
<UML:Parameter kind="return" xmi.id="ucaCke3ef6TFo" type="ufgglRaUHqAMn"/>
<UML:Parameter visibility="private" isSpecification="false" xmi.id="u5kLFla8n2s4A" type="ufgglRaUHqAMn" value="" comment="Config's section name" name="sec_name"/>
<UML:Parameter visibility="private" isSpecification="false" xmi.id="uxEbQOpS5hUIk" type="ufgglRaUHqAMn" value="" comment="Name of config property" name="property"/>
</UML:BehavioralFeature.parameter>
</UML:Operation>
<UML:Operation visibility="public" isSpecification="false" isQuery="false" isAbstract="false" isLeaf="false" isRoot="false" xmi.id="usn7OXmHFZ0V5" comment="Provides a list of the image cropping related settings for the given config section in the following order:&#xa;&#xa;[CROP_X, CROP_Y, CROP_W, CROP_H]" isOverride="false" name="get_crop_settings_as_list" isInline="false" isVirtual="false">
<UML:BehavioralFeature.parameter>
<UML:Parameter kind="return" xmi.id="uEF4qeJoY2c1R" type="uSN9tVhGt4JeL"/>
<UML:Parameter visibility="private" isSpecification="false" xmi.id="ueTgrhoNnyuV8" type="ufgglRaUHqAMn" value="" comment="Config's section name" name="sec_name"/>
</UML:BehavioralFeature.parameter>
</UML:Operation>
<UML:Operation visibility="public" isSpecification="false" isQuery="false" isAbstract="false" isLeaf="false" isRoot="false" xmi.id="uSGnhkrHFPLJe" comment="Getter for all config data. Returns data in a nested Map. All config sections have the key of section name, and are the value of a Map containing the keys and values." isOverride="false" name="get_cfg" isInline="false" isVirtual="false">
<UML:BehavioralFeature.parameter>
<UML:Parameter kind="return" xmi.id="u9wv8ZFiOMY8s" type="unEKbNBpRDYxe"/>
<UML:Parameter visibility="private" isSpecification="false" xmi.id="uLgAsQcamlJkr" type="uzncWu1t5XAqV" value="False" comment="Whether to include the &quot;DEFAULT&quot; section in the config data returned" name="include_default"/>
</UML:BehavioralFeature.parameter>
</UML:Operation>
<UML:Operation visibility="public" isSpecification="false" isQuery="false" isAbstract="false" isLeaf="false" isRoot="false" xmi.id="uLNiFClGsFzcu" comment="Adds a new section with the next available default name to this config. &#xa;Returns the name of the newly created section." isOverride="false" name="add_device_section" isInline="false" isVirtual="false">
<UML:BehavioralFeature.parameter>
<UML:Parameter kind="return" xmi.id="uBjEXvAHDALSG" type="ufgglRaUHqAMn"/>
</UML:BehavioralFeature.parameter>
</UML:Operation>
<UML:Operation visibility="public" isSpecification="false" isQuery="false" isAbstract="false" isLeaf="false" isRoot="false" xmi.id="uTwlbMfaiRTi5" comment="Adds a section with the given name to this config&#x9;" isOverride="false" name="add_custom_section" isInline="false" isVirtual="false">
<UML:BehavioralFeature.parameter>
<UML:Parameter visibility="private" isSpecification="false" xmi.id="ulYHAQ1rJTulL" type="ufgglRaUHqAMn" value="" comment="New section name" name="sec_name"/>
</UML:BehavioralFeature.parameter>
</UML:Operation>
<UML:Operation visibility="public" isSpecification="false" isQuery="false" isAbstract="false" isLeaf="false" isRoot="false" xmi.id="ufBYXnRBO8t2W" comment="Sets the given property in the given config section to the given value.&#xa;&#xa;If the given config section does not exist, a new section will be made, then the property set." isOverride="false" name="set_property" isInline="false" isVirtual="false">
<UML:BehavioralFeature.parameter>
<UML:Parameter visibility="private" isSpecification="false" xmi.id="uvoOfWxAN3DHf" type="ufgglRaUHqAMn" value="" comment="Config's section name" name="sec_name"/>
<UML:Parameter visibility="private" isSpecification="false" xmi.id="um0W3bQzwAqBC" type="ufgglRaUHqAMn" value="" comment="Config's property to set" name="property"/>
<UML:Parameter visibility="private" isSpecification="false" xmi.id="uI0xZNQRkAT8L" type="ufgglRaUHqAMn" value="" comment="String of the value to set for the given property" name="value"/>
</UML:BehavioralFeature.parameter>
</UML:Operation>
<UML:Operation visibility="public" isSpecification="false" isQuery="false" isAbstract="false" isLeaf="false" isRoot="false" xmi.id="ulqCSHhgfAqqc" comment="Returns a list of the names of this config's sections" isOverride="false" name="sections" isInline="false" isVirtual="false">
<UML:BehavioralFeature.parameter>
<UML:Parameter kind="return" xmi.id="ubJRwrANCenTT" type="uSN9tVhGt4JeL"/>
</UML:BehavioralFeature.parameter>
</UML:Operation>
</UML:Classifier.feature>
</UML:Class>
<UML:Association visibility="public" isSpecification="false" namespace="Logical_View" xmi.id="uOVEhx9DlR5su" name="">
<UML:Association.connection>
<UML:AssociationEnd changeability="changeable" visibility="public" isNavigable="true" isSpecification="false" xmi.id="uZiyrC3bK6NMK" type="uzwE2u8G0m86m" name="" aggregation="composite"/>
<UML:AssociationEnd changeability="changeable" visibility="public" isNavigable="true" isSpecification="false" xmi.id="uwrvkDEUmqLig" type="ue6uiThNgNDFB" name="" aggregation="none"/>
</UML:Association.connection>
</UML:Association>
<UML:Association visibility="public" isSpecification="false" namespace="Logical_View" xmi.id="uLrU6WaiY85PK" name="">
<UML:Association.connection>
<UML:AssociationEnd changeability="changeable" visibility="public" isNavigable="true" isSpecification="false" xmi.id="uDDiCwPJtklXo" type="u6VqpQtja46wn" name="" aggregation="composite"/>
<UML:AssociationEnd changeability="changeable" visibility="public" isNavigable="true" isSpecification="false" xmi.id="uPHQRAjzNWliM" type="uWZbdMIa5lsbb" name="" aggregation="none"/>
</UML:Association.connection>
</UML:Association>
<UML:Association visibility="public" isSpecification="false" namespace="Logical_View" xmi.id="uva3TQxmUNJco" name="">
<UML:Association.connection>
<UML:AssociationEnd changeability="changeable" visibility="public" isNavigable="true" isSpecification="false" xmi.id="uzu2hMRUAHeo7" type="uR5ObfNSeeXhB" name="" aggregation="composite"/>
<UML:AssociationEnd changeability="changeable" visibility="public" isNavigable="true" isSpecification="false" xmi.id="uUDPxJkutPDmT" type="unEKbNBpRDYxe" name="" aggregation="none"/>
</UML:Association.connection>
</UML:Association>
<UML:Association visibility="public" isSpecification="false" namespace="Logical_View" xmi.id="uyBcFlWGLJxz6" name="">
<UML:Association.connection>
<UML:AssociationEnd changeability="changeable" visibility="public" isNavigable="true" isSpecification="false" xmi.id="u4FmBQiB0zws9" type="u3PKuOJQ3ZHmI" name="" aggregation="composite"/>
<UML:AssociationEnd changeability="changeable" visibility="public" isNavigable="true" isSpecification="false" xmi.id="uXpuH0lWRvyJ2" type="uSN9tVhGt4JeL" name="" aggregation="none"/>
</UML:Association.connection>
</UML:Association>
<UML:Association visibility="public" isSpecification="false" namespace="Logical_View" xmi.id="uNTybpLy7tl7n" name="">
<UML:Association.connection>
<UML:AssociationEnd changeability="changeable" visibility="public" isNavigable="true" isSpecification="false" xmi.id="u0fvts2666K1Q" type="u3PKuOJQ3ZHmI" name="" aggregation="composite"/>
<UML:AssociationEnd changeability="changeable" visibility="public" isNavigable="true" isSpecification="false" xmi.id="uBmWA0SOCYpzT" type="ue6uiThNgNDFB" name="" aggregation="none"/>
</UML:Association.connection>
</UML:Association>
<UML:Class visibility="public" isSpecification="false" namespace="Logical_View" isAbstract="false" isLeaf="false" isRoot="false" xmi.id="uCW0AMheY8JMc" comment="Python library for interacting with config files. Will need to find a Java equivalent." name="ConfigParser"/>
<UML:Association visibility="public" isSpecification="false" namespace="Logical_View" xmi.id="u5MvuOAF5Hkwt" name="">
<UML:Association.connection>
<UML:AssociationEnd changeability="changeable" visibility="public" isNavigable="true" isSpecification="false" xmi.id="uPakYBWfdImok" type="uR5ObfNSeeXhB" name="" aggregation="composite"/>
<UML:AssociationEnd changeability="changeable" visibility="public" isNavigable="true" isSpecification="false" xmi.id="uJI8TDK0wnGcT" type="uSN9tVhGt4JeL" name="" aggregation="none"/>
</UML:Association.connection>
</UML:Association>
<UML:Association visibility="public" isSpecification="false" namespace="Logical_View" xmi.id="uIKgyJ1KsyuF6" name="">
<UML:Association.connection>
<UML:AssociationEnd changeability="changeable" visibility="public" isNavigable="true" isSpecification="false" xmi.id="uncF2KUT9POuG" type="uoU85LGuFdMDB" name="" aggregation="composite"/>
<UML:AssociationEnd changeability="changeable" visibility="public" isNavigable="true" isSpecification="false" xmi.id="uGyCJPmDCdnU9" type="uQ6I6JzsO2HGl" name="" aggregation="none"/>
</UML:Association.connection>
</UML:Association>
<UML:Association visibility="public" isSpecification="false" namespace="Logical_View" xmi.id="u0jU0s0jTNp1e" name="">
<UML:Association.connection>
<UML:AssociationEnd changeability="changeable" visibility="public" isNavigable="true" isSpecification="false" xmi.id="ukFm1AELngBAp" type="u3PKuOJQ3ZHmI" name="" aggregation="composite"/>
<UML:AssociationEnd changeability="changeable" visibility="public" isNavigable="true" isSpecification="false" xmi.id="ub4i24hX071Tp" type="uDw2wLV7OL4hx" name="" aggregation="none"/>
</UML:Association.connection>
</UML:Association>
<UML:Interface stereotype="interface" visibility="public" isSpecification="false" namespace="Logical_View" isAbstract="true" isLeaf="false" isRoot="false" xmi.id="uwl3mL4D79Yo7" comment="MVC Observer interface" name="Observer">
<UML:Classifier.feature>
<UML:Operation visibility="public" isSpecification="false" isQuery="false" isAbstract="true" isLeaf="false" isRoot="false" xmi.id="u5IbfNv3J3Z8v" comment="Update the observer" isOverride="false" name="update" isInline="false" isVirtual="true"/>
</UML:Classifier.feature>
</UML:Interface>
<UML:Dependency visibility="public" isSpecification="false" namespace="Logical_View" supplier="uwl3mL4D79Yo7" xmi.id="u2ZvuTqGyJuBL" client="u3PKuOJQ3ZHmI" name=""/>
<UML:Association visibility="public" isSpecification="false" namespace="Logical_View" xmi.id="uDfVM5g16KwFK" name="">
<UML:Association.connection>
<UML:AssociationEnd changeability="changeable" visibility="public" isNavigable="false" isSpecification="false" xmi.id="uFJsvtUPvkr1i" type="u3PKuOJQ3ZHmI" name="" aggregation="none"/>
<UML:AssociationEnd changeability="changeable" visibility="public" isNavigable="true" isSpecification="false" xmi.id="uH45EfLFTIZUq" type="uoU85LGuFdMDB" name="" aggregation="none"/>
</UML:Association.connection>
</UML:Association>
<UML:Class visibility="public" isSpecification="false" namespace="Logical_View" isAbstract="false" isLeaf="false" isRoot="false" xmi.id="uuxstJ2dy9vxT" comment="TODO" name="log_tools"/>
<UML:Class visibility="public" isSpecification="false" namespace="Logical_View" isAbstract="false" isLeaf="false" isRoot="false" xmi.id="uaevmzQNQgKmj" comment="TODO" name="AnomalyDetector"/>
<UML:Enumeration stereotype="enum" visibility="public" isSpecification="false" namespace="Logical_View" isAbstract="false" isLeaf="false" isRoot="false" xmi.id="u77iMFNAED177" comment="TODO" name="DMode">
<UML:Enumeration.literal>
<UML:EnumerationLiteral visibility="public" isSpecification="false" namespace="u77iMFNAED177" isAbstract="false" isLeaf="false" isRoot="false" xmi.id="ulr7ywjKJFqKv" value="1" name="RUNNING_MEAN"/>
<UML:EnumerationLiteral visibility="public" isSpecification="false" namespace="u77iMFNAED177" isAbstract="false" isLeaf="false" isRoot="false" xmi.id="ugzTrox5Tq0Bz" value="2" name="DIFFERENCE"/>
</UML:Enumeration.literal>
</UML:Enumeration>
<UML:Dependency visibility="public" isSpecification="false" namespace="Logical_View" supplier="u77iMFNAED177" xmi.id="uO9M4QiEVrFyA" client="uaevmzQNQgKmj" name=""/>
<UML:Dependency visibility="public" isSpecification="false" namespace="Logical_View" supplier="uuxstJ2dy9vxT" xmi.id="uLYm1Id63ECFB" client="uaevmzQNQgKmj" name=""/>
<UML:Dependency visibility="public" isSpecification="false" namespace="Logical_View" supplier="uuxstJ2dy9vxT" xmi.id="uhHX0XOxFQPhS" client="u3PKuOJQ3ZHmI" name=""/>
<UML:Association visibility="public" isSpecification="false" namespace="Logical_View" xmi.id="upLvMLwon443G" name="">
<UML:Association.connection>
<UML:AssociationEnd changeability="changeable" visibility="public" isNavigable="true" isSpecification="false" xmi.id="uZG935OZerOou" type="uuxstJ2dy9vxT" name="" aggregation="none"/>
<UML:AssociationEnd changeability="changeable" visibility="public" isNavigable="true" isSpecification="false" xmi.id="un8Qvb9G2VbAz" type="uaevmzQNQgKmj" name="" aggregation="none"/>
</UML:Association.connection>
</UML:Association>
<UML:Class visibility="public" isSpecification="false" namespace="Logical_View" isAbstract="false" isLeaf="false" isRoot="false" xmi.id="ufQnO4lKJJOqQ" comment="TODO" name="camera_tools">
<UML:Classifier.feature>
<UML:Operation visibility="public" isSpecification="false" isQuery="false" isAbstract="false" isLeaf="false" ownerScope="classifier" isRoot="false" xmi.id="uyfsEqdxKqZoC" comment="Constructor for an OpenCV VideoCapture object.&#xa;&#xa;Sets frame width and height based on given values. &#xa;Sets fourcc property to MJPG. fourcc stands for Four Character Code, and is a standard way of denoting video/image codecs. Our ArduCams are currently only capable of creating MJPG and YUY2 images, and OpenCV and Tesseract are only compatible with MJPG." isOverride="false" name="mk_VideoCapture" isInline="false" isVirtual="false">
<UML:BehavioralFeature.parameter>
<UML:Parameter kind="return" xmi.id="uXrKKNcDuJYfp" type="uDw2wLV7OL4hx"/>
<UML:Parameter visibility="private" isSpecification="false" xmi.id="uov5IZCOC1RO0" type="ufgglRaUHqAMn" value="" comment="The port for the video camera" name="port"/>
<UML:Parameter visibility="private" isSpecification="false" xmi.id="u9gciPDeUalsW" type="uC8n0yHzYaFtW" value="800" comment="Width of the image frame in pixels" name="width"/>
<UML:Parameter visibility="private" isSpecification="false" xmi.id="ux1xfzlgbKrVd" type="uC8n0yHzYaFtW" value="600" comment="Height of the image frame in pixels" name="height"/>
</UML:BehavioralFeature.parameter>
</UML:Operation>
<UML:Operation visibility="public" isSpecification="false" isQuery="false" isAbstract="false" isLeaf="false" ownerScope="classifier" isRoot="false" xmi.id="uM6ZHX24fBYDF" comment="Grabs most recent frame from the video stream. This function is to be used when a video stream is not being read from continuously (i.e. in a loop), but the caller wants to take a picture by getting the last frame obtained. The caller will likely want to follow this function with a call to capture.retrieve() to decode the grabbed frame." isOverride="false" name="grab_most_recent" isInline="false" isVirtual="false">
<UML:BehavioralFeature.parameter>
<UML:Parameter kind="return" xmi.id="uffV7kn3migJk" type="uzncWu1t5XAqV"/>
<UML:Parameter visibility="private" isSpecification="false" xmi.id="uH6I0rur12rqe" type="uDw2wLV7OL4hx" value="" comment="OpenCV VideoCapture object" name="capture"/>
</UML:BehavioralFeature.parameter>
</UML:Operation>
<UML:Operation visibility="public" isSpecification="false" isQuery="false" isAbstract="false" isLeaf="false" ownerScope="classifier" isRoot="false" xmi.id="unKiaC72rI4rD" comment="Shows a single still image in a window using Python's cv2.imshow() and cv2.waitKey(). If a window with the given title already exists, it is destroyed and a new window is displayed. " isOverride="false" name="show_still_img" isInline="false" isVirtual="false">
<UML:BehavioralFeature.parameter>
<UML:Parameter visibility="private" isSpecification="false" xmi.id="uOTivDaVu4scI" type="ue6uiThNgNDFB" value="" comment="Raw image" name="img"/>
<UML:Parameter visibility="private" isSpecification="false" xmi.id="uc4gSYR88P5eP" type="ufgglRaUHqAMn" value="" comment="Title of the window" name="title"/>
<UML:Parameter visibility="private" isSpecification="false" xmi.id="uHjkFhoYS26Nl" type="ut3U2TtHTDMqm" value="0" comment="Amount of time in milliseconds to delay before the window closes itself." name="delay"/>
</UML:BehavioralFeature.parameter>
</UML:Operation>
<UML:Operation visibility="public" isSpecification="false" isQuery="false" isAbstract="false" isLeaf="false" ownerScope="classifier" isRoot="false" xmi.id="uUdzbcmeA8Gxb" comment="Saves a raw image to the given path." isOverride="false" name="save_img" isInline="false" isVirtual="false">
<UML:BehavioralFeature.parameter>
<UML:Parameter visibility="private" isSpecification="false" xmi.id="u8Iwx8gTtCt8K" type="ue6uiThNgNDFB" value="" comment="Raw image to be saved" name="img"/>
<UML:Parameter visibility="private" isSpecification="false" xmi.id="uEqcZXKv1vzqS" type="ufgglRaUHqAMn" value="" comment="Path to save the image to" name="path"/>
</UML:BehavioralFeature.parameter>
</UML:Operation>
<UML:Operation visibility="public" isSpecification="false" isQuery="false" isAbstract="false" isLeaf="false" ownerScope="classifier" isRoot="false" xmi.id="uI4dZ7OZj6Dck" comment="Crops an image by returning the subset of the input array that correponds to the crop parameters. " isOverride="false" name="crop" isInline="false" isVirtual="false">
<UML:BehavioralFeature.parameter>
<UML:Parameter kind="return" xmi.id="uUA4LIAnTMGQb" type="ue6uiThNgNDFB"/>
<UML:Parameter visibility="private" isSpecification="false" xmi.id="u7Yhijt8H6VfA" type="ue6uiThNgNDFB" value="" comment="raw image to crop" name="img"/>
<UML:Parameter visibility="private" isSpecification="false" xmi.id="ukjvg5Y0ACP2t" type="uC8n0yHzYaFtW" value="" comment="x-coordinate of the cropped image's upper-left corner" name="x"/>
<UML:Parameter visibility="private" isSpecification="false" xmi.id="uN4JgWSBIqIGR" type="uC8n0yHzYaFtW" value="" comment="y-coordinate of the cropped image's upper-left corner" name="y"/>
<UML:Parameter visibility="private" isSpecification="false" xmi.id="uR4JahhS9FJRS" type="uC8n0yHzYaFtW" value="" comment="width in pixels of the cropped image, extending right from x" name="w"/>
<UML:Parameter visibility="private" isSpecification="false" xmi.id="uBQEFYMUZmEbh" type="uC8n0yHzYaFtW" value="" comment="height in pixels of the cropped image, extending down from the given y" name="h"/>
</UML:BehavioralFeature.parameter>
</UML:Operation>
<UML:Operation visibility="public" isSpecification="false" isQuery="false" isAbstract="false" isLeaf="false" ownerScope="classifier" isRoot="false" xmi.id="uFKAtmpK3IMid" comment="Converts a frame to greyscale and processes it through a binary threshold. Any value under 127 (not including 127) gets a value of 0 (black). Any value above and including 127 gets a value of 255 (white). Applies a gamma adjustment using the following formula (used before the threshold)&#xa;&#xa;value_out = value_in ^ gamma&#xa;&#xa;" isOverride="false" name="binary_threshold" isInline="false" isVirtual="false">
<UML:BehavioralFeature.parameter>
<UML:Parameter kind="return" xmi.id="u1FYm8YzeA35z" type="ue6uiThNgNDFB"/>
<UML:Parameter visibility="private" isSpecification="false" xmi.id="uEO3qXgIL9bpd" type="ue6uiThNgNDFB" value="" comment="Raw image to be thresholded" name="frame"/>
<UML:Parameter visibility="private" isSpecification="false" xmi.id="uD1SFligXea0P" type="ut3U2TtHTDMqm" value="1.0" comment="Gamma modifier for the raw image" name="gamma"/>
</UML:BehavioralFeature.parameter>
</UML:Operation>
<UML:Operation visibility="public" isSpecification="false" isQuery="false" isAbstract="false" isLeaf="false" ownerScope="classifier" isRoot="false" xmi.id="u5cgflHGyG5Wy" comment="Helper function that obtains all frames for a composite image, applies the binary threshold, and composes all the thresholded frames into a final image using bitwise AND to keep all black pixels from all frames. If threshold is False, this function simply reads and returns a single unedited frame." isOverride="false" name="compose_img" isInline="false" isVirtual="false">
<UML:BehavioralFeature.parameter>
<UML:Parameter kind="return" xmi.id="uEErAzqeGGBfs" type="ue6uiThNgNDFB"/>
<UML:Parameter visibility="private" isSpecification="false" xmi.id="u2ONN3QRPThtP" type="uDw2wLV7OL4hx" value="" comment="OpenCV VideoCapture object" name="capture"/>
<UML:Parameter visibility="private" isSpecification="false" xmi.id="u7UGnzMT9VDlh" type="uzncWu1t5XAqV" value="" comment="Whether or not to apply a binary threshold to the image" name="threshold"/>
<UML:Parameter visibility="private" isSpecification="false" xmi.id="uqvMbkvDc3PpN" type="ut3U2TtHTDMqm" value="" comment="Gamma adjustment for the binary thresholding (only used if threshold is True)" name="gamma"/>
<UML:Parameter visibility="private" isSpecification="false" xmi.id="uekPYyIrG3MBW" type="uC8n0yHzYaFtW" value="" comment="Number of frames to use for the composite image (only used if threshold is True)" name="c_frames"/>
<UML:Parameter visibility="private" isSpecification="false" xmi.id="urU7tC5y241gW" type="uzncWu1t5XAqV" value="" comment="Whether to crop the image" name="crop_img"/>
<UML:Parameter visibility="private" isSpecification="false" xmi.id="uo66prX3eyqOS" type="uC8n0yHzYaFtW" value="" comment="x value for the crop function (only used if crop is True)" name="x"/>
<UML:Parameter visibility="private" isSpecification="false" xmi.id="uZeh6rC17f44E" type="uC8n0yHzYaFtW" value="" comment="y value for the crop function (only used if crop is True)" name="y"/>
<UML:Parameter visibility="private" isSpecification="false" xmi.id="uGgLwxbF1tdrL" type="uC8n0yHzYaFtW" value="" comment="w value for the crop function (only used if crop is True)" name="w"/>
<UML:Parameter visibility="private" isSpecification="false" xmi.id="uJmBWcTa1XetW" type="uC8n0yHzYaFtW" value="" comment="h value for the crop function (only used if crop is True)" name="h"/>
</UML:BehavioralFeature.parameter>
</UML:Operation>
<UML:Operation visibility="public" isSpecification="false" isQuery="false" isAbstract="false" isLeaf="false" isRoot="false" xmi.id="udlBYvFW4qCAE" comment="mk_img_player() is a function that.... returns a function [play()]? Which is used in another function in the Python version of this diagram [mk_img_player_thread()]. This is then used in run_camera(), which returns a VideoCapture object and the thread returned by mk_img_player_thread(). Since these functions are non-trivial to convert to Java, they have been simplified into this comment." isOverride="false" name="player_functions" isInline="false" isVirtual="true"/>
<UML:Operation visibility="public" isSpecification="false" isQuery="false" isAbstract="false" isLeaf="false" ownerScope="classifier" isRoot="false" xmi.id="uNJuqryn6sANI" comment="Runs the camera device on the given port. This function is isolated from all others in the module, and may be used as a standalone camera or player. " isOverride="false" name="run_camera_simple" isInline="false" isVirtual="false">
<UML:BehavioralFeature.parameter>
<UML:Parameter visibility="private" isSpecification="false" xmi.id="uOzqas1ynKJMO" type="ufgglRaUHqAMn" value="&quot;/dev/video0&quot;" comment="Video port for the camera's video stream" name="port"/>
<UML:Parameter visibility="private" isSpecification="false" xmi.id="ugG2eR5vMFwR3" type="uC8n0yHzYaFtW" value="800" comment="Width of the video stream frame, in pixels" name="cap_width"/>
<UML:Parameter visibility="private" isSpecification="false" xmi.id="uCZUDS4kWPenY" type="uC8n0yHzYaFtW" value="600" comment="height of the video stream frame, in pixels" name="cap_height"/>
<UML:Parameter visibility="private" isSpecification="false" xmi.id="uvfyRduuj4MLE" type="uzncWu1t5XAqV" value="False" comment="Whether to process the video frames through grayscaling and a binary threshold" name="threshold"/>
<UML:Parameter visibility="private" isSpecification="false" xmi.id="u5szMbBEcJ0Sa" type="ut3U2TtHTDMqm" value="1.0" comment="Gamma adjustment to apply before thresholding (only applies if threshold == True)" name="gamma"/>
<UML:Parameter visibility="private" isSpecification="false" xmi.id="ukLpxtsZtq8lQ" type="uC8n0yHzYaFtW" value="1" comment="number of frames to use in the composite image (only used if threshold == True)" name="composite_frames"/>
</UML:BehavioralFeature.parameter>
</UML:Operation>
</UML:Classifier.feature>
</UML:Class>
<UML:Class visibility="public" isSpecification="false" namespace="Logical_View" isAbstract="false" isLeaf="false" isRoot="false" xmi.id="u9nAYpyG3aSi9" comment="TODO" name="compose_img_cap_func"/>
<UML:Class visibility="public" isSpecification="false" namespace="Logical_View" isAbstract="false" isLeaf="false" isRoot="false" xmi.id="u7TjMMyLbs3BP" comment="TODO" name="feature_detection_processing_func"/>
<UML:Dependency visibility="public" isSpecification="false" namespace="Logical_View" supplier="ufQnO4lKJJOqQ" xmi.id="uRA8xnAP8hPLu" client="u3PKuOJQ3ZHmI" name=""/>
<UML:Dependency visibility="public" isSpecification="false" namespace="Logical_View" supplier="uwl3mL4D79Yo7" xmi.id="u5CgnNl5HfULt" client="uGAAftKX0LKPe" name="Implementation"/>
<UML:Class visibility="public" isSpecification="false" namespace="Logical_View" isAbstract="false" isLeaf="false" isRoot="false" xmi.id="u3OjgIBqJBgyn" comment="Worker object for running an accuracy over life test on a given fixture in a separate QThread." name="AOLWorker"/>
</UML:Namespace.ownedElement>
<XMI.extension xmi.extender="umbrello">
<diagrams resolution="192">
<diagram showopsig="1" linecolor="#ff0000" snapx="25" showattribassocs="1" snapy="25" linewidth="0" showattsig="1" textcolor="#000000" isopen="1" showpackage="1" showpubliconly="0" showstereotype="1" name="class diagram" font="72,9,-1,5,50,0,0,0,0,0" canvasheight="3478.62" canvaswidth="3403.04" localid="-1" snapcsgrid="0" showgrid="1" showops="1" griddotcolor="#f6f6f6" backgroundcolor="#ffffff" usefillcolor="1" fillcolor="#ffffc0" zoom="61.52787621294764" xmi.id="uh50sSCS4d9CW" documentation="" showscope="1" snapgrid="0" showatts="1" type="1">
<widgets>
<classwidget linecolor="#ff0000" usesdiagramfillcolor="0" linewidth="0" textcolor="#000000" showoperations="1" usesdiagramusefillcolor="0" showpubliconly="0" showpackage="1" x="-2845.17" showattsigs="601" showstereotype="1" y="-1878.72" showattributes="1" font="72,9,-1,5,50,0,0,0,0,0" localid="ub72UYXcJXq7L" width="646.611" isinstance="0" usefillcolor="1" fillcolor="#ffff00" xmi.id="uzwE2u8G0m86m" autoresize="0" showscope="1" height="104.661" showopsigs="601"/>
<classwidget linecolor="#ff0000" usesdiagramfillcolor="0" linewidth="0" textcolor="#000000" showoperations="1" usesdiagramusefillcolor="0" showpubliconly="0" showpackage="1" x="-2183.46" showattsigs="601" showstereotype="1" y="-2775.09" showattributes="1" font="72,9,-1,5,50,0,0,0,0,0" localid="u0SyLgHkjUp0M" width="658" isinstance="0" usefillcolor="1" fillcolor="#ffff00" xmi.id="uoU85LGuFdMDB" autoresize="1" showscope="1" height="580" showopsigs="601"/>
<classwidget linecolor="#ff0000" usesdiagramfillcolor="0" linewidth="0" textcolor="#000000" showoperations="1" usesdiagramusefillcolor="0" showpubliconly="0" showpackage="1" x="-1772.1" showattsigs="601" showstereotype="1" y="-3854.89" showattributes="1" font="72,9,-1,5,50,0,0,0,0,0" localid="uufYEm8xPkDyM" width="368" isinstance="0" usefillcolor="1" fillcolor="#ffff00" xmi.id="uThfpCkW5KNLv" autoresize="1" showscope="1" height="145" showopsigs="601"/>
<classwidget linecolor="#ff0000" usesdiagramfillcolor="0" linewidth="0" textcolor="#000000" showoperations="1" usesdiagramusefillcolor="0" showpubliconly="0" showpackage="1" x="-3559.47" showattsigs="601" showstereotype="1" y="-3324.51" showattributes="1" font="72,9,-1,5,50,0,0,0,0,0" localid="uaSqRJGVrXAPU" width="709" isinstance="0" usefillcolor="1" fillcolor="#ffff00" xmi.id="u3PKuOJQ3ZHmI" autoresize="1" showscope="1" height="1160" showopsigs="601"/>
<classwidget linecolor="#ff0000" usesdiagramfillcolor="0" linewidth="0" textcolor="#000000" showoperations="1" usesdiagramusefillcolor="0" showpubliconly="0" showpackage="1" x="-2977.38" showattsigs="601" showstereotype="1" y="-4086.45" showattributes="1" font="72,9,-1,5,50,0,0,0,0,0" localid="u2NgrrlnVdaFK" width="1000" isinstance="0" usefillcolor="1" fillcolor="#ffff00" xmi.id="uGAAftKX0LKPe" autoresize="1" showscope="1" height="130" showopsigs="601"/>
<classwidget linecolor="#ff0000" usesdiagramfillcolor="0" linewidth="0" textcolor="#000000" showoperations="1" usesdiagramusefillcolor="0" showpubliconly="0" showpackage="1" x="-3969.53" showattsigs="601" showstereotype="1" y="-1919.14" showattributes="1" font="72,9,-1,5,50,0,0,0,0,0" localid="uDjNohIZnr92L" width="1000" isinstance="0" usefillcolor="1" fillcolor="#ffff00" xmi.id="uR5ObfNSeeXhB" autoresize="1" showscope="1" height="1102" showopsigs="601"/>
<datatypewidget width="52" showstereotype="1" x="-4084.56" usesdiagramusefillcolor="0" y="-2238.17" usesdiagramfillcolor="0" isinstance="0" localid="uonJrNDjnn7QL" fillcolor="#ffff00" height="58" linecolor="#ff0000" xmi.id="uSN9tVhGt4JeL" autoresize="1" textcolor="#000000" usefillcolor="1" linewidth="0" font="72,9,-1,5,50,0,0,0,0,0"/>
<datatypewidget width="59" showstereotype="1" x="-4409.47" usesdiagramusefillcolor="0" y="-1072.9" usesdiagramfillcolor="0" isinstance="0" localid="uSfl5mM3RA482" fillcolor="#ffff00" height="58" linecolor="#ff0000" xmi.id="unEKbNBpRDYxe" autoresize="1" textcolor="#000000" usefillcolor="1" linewidth="0" font="72,9,-1,5,50,0,0,0,0,0"/>
<datatypewidget width="72" showstereotype="1" x="-2063.77" usesdiagramusefillcolor="0" y="-1889.28" usesdiagramfillcolor="0" isinstance="0" localid="ua0jZwhent0g1" fillcolor="#ffff00" height="58" linecolor="#ff0000" xmi.id="ue6uiThNgNDFB" autoresize="1" textcolor="#000000" usefillcolor="1" linewidth="0" font="72,9,-1,5,50,0,0,0,0,0"/>
<classwidget linecolor="#ff0000" usesdiagramfillcolor="0" linewidth="0" textcolor="#000000" showoperations="1" usesdiagramusefillcolor="0" showpubliconly="0" showpackage="1" x="-3278.23" showattsigs="601" showstereotype="1" y="-664.832" showattributes="1" font="72,9,-1,5,50,0,0,0,0,0" localid="uHa4fWvpOe0tW" width="158" isinstance="0" usefillcolor="1" fillcolor="#ffff00" xmi.id="uCW0AMheY8JMc" autoresize="1" showscope="1" height="57" showopsigs="601"/>
<datatypewidget width="33" showstereotype="1" x="-1509.78" usesdiagramusefillcolor="0" y="-2006.53" usesdiagramfillcolor="0" isinstance="0" localid="uByXWt3CshjN0" fillcolor="#ffff00" height="58" linecolor="#ff0000" xmi.id="uQ6I6JzsO2HGl" autoresize="1" textcolor="#000000" usefillcolor="1" linewidth="0" font="72,9,-1,5,50,0,0,0,0,0"/>
<datatypewidget width="166" showstereotype="1" x="-4339.06" usesdiagramusefillcolor="0" y="-2552.03" usesdiagramfillcolor="0" isinstance="0" localid="u1rNeUXXkfu0N" fillcolor="#ffff00" height="58" linecolor="#ff0000" xmi.id="uDw2wLV7OL4hx" autoresize="1" textcolor="#000000" usefillcolor="1" linewidth="0" font="72,9,-1,5,50,0,0,0,0,0"/>
<interfacewidget linecolor="#ff0000" usesdiagramfillcolor="0" linewidth="0" textcolor="#000000" showoperations="1" usesdiagramusefillcolor="0" showpubliconly="0" showpackage="0" x="-3351.42" showattsigs="601" showstereotype="1" y="-3557.69" showattributes="0" font="72,9,-1,5,50,0,0,0,0,0" drawascircle="0" localid="ujtvfl2D3UHlI" width="135" isinstance="0" usefillcolor="1" fillcolor="#ffff00" xmi.id="uwl3mL4D79Yo7" autoresize="1" showscope="1" height="87" showopsigs="601"/>
<classwidget linecolor="#ff0000" usesdiagramfillcolor="0" linewidth="0" textcolor="#000000" showoperations="1" usesdiagramusefillcolor="0" showpubliconly="0" showpackage="1" x="-4807.14" showattsigs="601" showstereotype="1" y="-3273.21" showattributes="1" font="72,9,-1,5,50,0,0,0,0,0" localid="uiQPqwYNokaIy" width="1000" isinstance="0" usefillcolor="1" fillcolor="#ffff00" xmi.id="ufQnO4lKJJOqQ" autoresize="1" showscope="1" height="304" showopsigs="601"/>
<classwidget linecolor="#ff0000" usesdiagramfillcolor="0" linewidth="0" textcolor="#000000" showoperations="1" usesdiagramusefillcolor="0" showpubliconly="0" showpackage="1" x="-2536.33" showattsigs="601" showstereotype="1" y="-3655.9" showattributes="1" font="72,9,-1,5,50,0,0,0,0,0" localid="uuCFvkbLsGi8q" width="141" isinstance="0" usefillcolor="1" fillcolor="#ffffc0" xmi.id="u3OjgIBqJBgyn" autoresize="1" showscope="1" height="57" showopsigs="601"/>
</widgets>
<messages/>
<associations>
<assocwidget indexa="1" linecolor="#ff0000" usesdiagramfillcolor="1" widgetbid="uoU85LGuFdMDB" indexb="1" linewidth="0" seqnum="" textcolor="none" usesdiagramusefillcolor="1" totalcounta="2" totalcountb="2" widgetaid="uThfpCkW5KNLv" font="Sans Serif,9,-1,0,50,0,0,0,0,0" localid="uXvElstgORzRS" usefillcolor="1" fillcolor="none" xmi.id="udaV98vJAtD5V" autoresize="1" type="502">
<linepath layout="Direct">
<startpoint startx="-1572.11" starty="-3709.89"/>
<endpoint endx="-1572.11" endy="-2775.09"/>
</linepath>
</assocwidget>
<assocwidget indexa="1" linecolor="#ff0000" usesdiagramfillcolor="1" widgetbid="uGAAftKX0LKPe" indexb="1" linewidth="0" seqnum="" textcolor="none" usesdiagramusefillcolor="1" totalcounta="2" totalcountb="2" widgetaid="uThfpCkW5KNLv" font="Sans Serif,9,-1,0,50,0,0,0,0,0" localid="uewxYD5Uj4E1b" usefillcolor="1" fillcolor="none" xmi.id="uy1xEgXwf84zo" autoresize="1" type="502">
<linepath layout="Direct">
<startpoint startx="-1772.1" starty="-3854.89"/>
<endpoint endx="-1977.38" endy="-3956.45"/>
</linepath>
</assocwidget>
<assocwidget indexa="1" linecolor="#ff0000" usesdiagramfillcolor="1" widgetbid="u3PKuOJQ3ZHmI" indexb="1" linewidth="0" seqnum="" textcolor="none" usesdiagramusefillcolor="1" totalcounta="2" totalcountb="2" widgetaid="uGAAftKX0LKPe" font="Sans Serif,9,-1,0,50,0,0,0,0,0" localid="uKL3rRx3Bad1X" usefillcolor="1" fillcolor="none" xmi.id="ue5VpiyFv6Lgr" autoresize="1" type="502">
<linepath layout="Direct">
<startpoint startx="-2869.47" starty="-3956.45"/>
<endpoint endx="-2869.47" endy="-3324.51"/>
</linepath>
</assocwidget>
<assocwidget indexa="1" linecolor="#ff0000" usesdiagramfillcolor="1" widgetbid="ue6uiThNgNDFB" indexb="1" linewidth="0" seqnum="" textcolor="none" usesdiagramusefillcolor="1" totalcounta="2" totalcountb="2" widgetaid="uzwE2u8G0m86m" font="Sans Serif,9,-1,0,50,0,0,0,0,0" localid="uQdjjbqFJ3Y8d" usefillcolor="1" fillcolor="none" xmi.id="uOVEhx9DlR5su" autoresize="1" type="510">
<linepath layout="Direct">
<startpoint startx="-2198.56" starty="-1833.28"/>
<endpoint endx="-2063.77" endy="-1833.28"/>
</linepath>
</assocwidget>
<assocwidget indexa="1" linecolor="#ff0000" usesdiagramfillcolor="1" widgetbid="unEKbNBpRDYxe" indexb="1" linewidth="0" seqnum="" textcolor="none" usesdiagramusefillcolor="1" totalcounta="2" totalcountb="2" widgetaid="uR5ObfNSeeXhB" font="Sans Serif,9,-1,0,50,0,0,0,0,0" localid="u0ryeR1FETLYP" usefillcolor="1" fillcolor="none" xmi.id="uva3TQxmUNJco" autoresize="1" type="510">
<linepath layout="Direct">
<startpoint startx="-3969.53" starty="-1049.96"/>
<endpoint endx="-4350.47" endy="-1049.96"/>
</linepath>
</assocwidget>
<assocwidget indexa="1" linecolor="#ff0000" usesdiagramfillcolor="1" widgetbid="uSN9tVhGt4JeL" indexb="1" linewidth="0" seqnum="" textcolor="none" usesdiagramusefillcolor="1" totalcounta="2" totalcountb="2" widgetaid="u3PKuOJQ3ZHmI" font="Sans Serif,9,-1,0,50,0,0,0,0,0" localid="uLvJXzTQCMXOw" usefillcolor="1" fillcolor="none" xmi.id="uyBcFlWGLJxz6" autoresize="1" type="510">
<linepath layout="Direct">
<startpoint startx="-3559.47" starty="-2238.17"/>
<endpoint endx="-4032.56" endy="-2238.17"/>
</linepath>
</assocwidget>
<assocwidget indexa="1" linecolor="#ff0000" usesdiagramfillcolor="1" widgetbid="ue6uiThNgNDFB" indexb="1" linewidth="0" seqnum="" textcolor="none" usesdiagramusefillcolor="1" totalcounta="2" totalcountb="2" widgetaid="u3PKuOJQ3ZHmI" font="Sans Serif,9,-1,0,50,0,0,0,0,0" localid="u8ixnCbOJhSJ7" usefillcolor="1" fillcolor="none" xmi.id="uNTybpLy7tl7n" autoresize="1" type="510">
<linepath layout="Direct">
<startpoint startx="-2850.47" starty="-2164.51"/>
<endpoint endx="-2063.77" endy="-1889.28"/>
</linepath>
</assocwidget>
<assocwidget linecolor="#ff0000" indexa="1" usesdiagramfillcolor="1" widgetbid="uCW0AMheY8JMc" indexb="1" linewidth="0" seqnum="" textcolor="#000000" usesdiagramusefillcolor="1" totalcounta="2" totalcountb="2" widgetaid="uR5ObfNSeeXhB" font="Sans Serif,9,-1,0,50,0,0,0,0,0" visibilityA="1" visibilityB="1" localid="uCdctiPvHGLMt" usefillcolor="1" fillcolor="none" changeabilityA="900" xmi.id="u6UhY8WirooGu" changeabilityB="900" autoresize="1" type="510">
<linepath layout="Direct">
<startpoint startx="-3167.23" starty="-817.14"/>
<endpoint endx="-3167.23" endy="-664.832"/>
</linepath>
<floatingtext linecolor="#ff0000" usesdiagramfillcolor="1" linewidth="0" textcolor="none" usesdiagramusefillcolor="1" x="-3156.78" showstereotype="1" y="-723.739" text="parser" font="72,9,-1,5,50,0,0,0,0,0" localid="ujtNon0a61aHj" pretext="-" role="710" width="108" isinstance="0" posttext="" usefillcolor="1" fillcolor="none" xmi.id="u0ByGK1uUOC5z" autoresize="1" height="41"/>
</assocwidget>
<assocwidget indexa="1" linecolor="#ff0000" usesdiagramfillcolor="1" widgetbid="uSN9tVhGt4JeL" indexb="1" linewidth="0" seqnum="" textcolor="none" usesdiagramusefillcolor="1" totalcounta="2" totalcountb="2" widgetaid="uR5ObfNSeeXhB" font="Sans Serif,9,-1,0,50,0,0,0,0,0" localid="uDojTzf0KQWSI" usefillcolor="1" fillcolor="none" xmi.id="u5MvuOAF5Hkwt" autoresize="1" type="510">
<linepath layout="Direct">
<startpoint startx="-3969.53" starty="-1919.14"/>
<endpoint endx="-4032.56" endy="-2180.17"/>
</linepath>
</assocwidget>
<assocwidget linecolor="#ff0000" indexa="1" usesdiagramfillcolor="1" widgetbid="uSN9tVhGt4JeL" indexb="1" linewidth="0" seqnum="" textcolor="#000000" usesdiagramusefillcolor="1" totalcounta="2" totalcountb="2" widgetaid="uR5ObfNSeeXhB" font="Sans Serif,9,-1,0,50,0,0,0,0,0" visibilityA="0" visibilityB="0" localid="ueuNHhqfT7qN6" usefillcolor="1" fillcolor="none" changeabilityA="900" xmi.id="uyCGecgUq18Mv" changeabilityB="900" autoresize="1" type="510">
<linepath layout="Direct">
<startpoint startx="-3969.53" starty="-1919.14"/>
<endpoint endx="-4032.56" endy="-2180.17"/>
</linepath>
<floatingtext linecolor="#ff0000" usesdiagramfillcolor="1" linewidth="0" textcolor="none" usesdiagramusefillcolor="1" x="-4074.85" showstereotype="1" y="-2101.72" text="PROPERTY_NAMES" font="72,9,-1,5,50,0,0,0,0,0" localid="uM0tV3zpEI6CD" pretext="+" role="710" width="316" isinstance="0" posttext="" usefillcolor="1" fillcolor="none" xmi.id="ui0v2V3vlcwuu" autoresize="1" height="41"/>
</assocwidget>
<assocwidget linecolor="#ff0000" indexa="1" usesdiagramfillcolor="1" widgetbid="unEKbNBpRDYxe" indexb="1" linewidth="0" seqnum="" textcolor="#000000" usesdiagramusefillcolor="1" totalcounta="2" totalcountb="2" widgetaid="uR5ObfNSeeXhB" font="Sans Serif,9,-1,0,50,0,0,0,0,0" visibilityA="0" visibilityB="0" localid="uqYVTm1TvTtaf" usefillcolor="1" fillcolor="none" changeabilityA="900" xmi.id="uVyfgg9vCFyLF" changeabilityB="900" autoresize="1" type="510">
<linepath layout="Direct">
<startpoint startx="-3969.53" starty="-1049.96"/>
<endpoint endx="-4350.47" endy="-1049.96"/>
</linepath>
<floatingtext linecolor="#ff0000" usesdiagramfillcolor="1" linewidth="0" textcolor="none" usesdiagramusefillcolor="1" x="-4347.63" showstereotype="1" y="-1026.86" text="DEFAULT_CONFIG" font="72,9,-1,5,50,0,0,0,0,0" localid="uWFOBqwwXbwzN" pretext="+" role="710" width="293" isinstance="0" posttext="" usefillcolor="1" fillcolor="none" xmi.id="uevhFpd6qDAdw" autoresize="1" height="41"/>
</assocwidget>
<assocwidget indexa="1" linecolor="#ff0000" usesdiagramfillcolor="1" widgetbid="uQ6I6JzsO2HGl" indexb="1" linewidth="0" seqnum="" textcolor="none" usesdiagramusefillcolor="1" totalcounta="2" totalcountb="2" widgetaid="uoU85LGuFdMDB" font="Sans Serif,9,-1,0,50,0,0,0,0,0" localid="uUyaHx7QBrtXC" usefillcolor="1" fillcolor="none" xmi.id="uIKgyJ1KsyuF6" autoresize="1" type="510">
<linepath layout="Direct">
<startpoint startx="-1525.46" starty="-2195.09"/>
<endpoint endx="-1509.78" endy="-2006.53"/>
</linepath>
</assocwidget>
<assocwidget linecolor="#ff0000" indexa="1" usesdiagramfillcolor="1" widgetbid="uDw2wLV7OL4hx" indexb="1" linewidth="0" seqnum="" textcolor="none" usesdiagramusefillcolor="1" totalcounta="2" totalcountb="2" widgetaid="u3PKuOJQ3ZHmI" font="Sans Serif,9,-1,0,50,0,0,0,0,0" visibilityA="0" visibilityB="0" localid="u7OQuHSLCnPqd" usefillcolor="1" fillcolor="none" changeabilityA="900" xmi.id="ufIN4B2QLPgEQ" changeabilityB="900" autoresize="1" type="510">
<linepath layout="Direct">
<startpoint startx="-3559.47" starty="-2552.03"/>
<endpoint endx="-4173.06" endy="-2552.03"/>
</linepath>
<floatingtext linecolor="#ff0000" usesdiagramfillcolor="1" linewidth="0" textcolor="none" usesdiagramusefillcolor="1" x="-4172.02" showstereotype="1" y="-2547.02" text="cam1" font="72,9,-1,5,50,0,0,0,0,0" localid="uva6WA5Ki85KE" pretext="+" role="710" width="105" isinstance="0" posttext="" usefillcolor="1" fillcolor="none" xmi.id="uSjNA1dkoksXt" autoresize="1" height="41"/>
</assocwidget>
<assocwidget linecolor="#ff0000" indexa="1" usesdiagramfillcolor="1" widgetbid="uDw2wLV7OL4hx" indexb="1" linewidth="0" seqnum="" textcolor="none" usesdiagramusefillcolor="1" totalcounta="2" totalcountb="2" widgetaid="u3PKuOJQ3ZHmI" font="Sans Serif,9,-1,0,50,0,0,0,0,0" visibilityA="0" visibilityB="0" localid="uZ468Y1DlsCrQ" usefillcolor="1" fillcolor="none" changeabilityA="900" xmi.id="uL2g1QxGDWG8P" changeabilityB="900" autoresize="1" type="510">
<linepath layout="Direct">
<startpoint startx="-3559.47" starty="-2552.03"/>
<endpoint endx="-4173.06" endy="-2552.03"/>
</linepath>
<floatingtext linecolor="#ff0000" usesdiagramfillcolor="1" linewidth="0" textcolor="none" usesdiagramusefillcolor="1" x="-4086.23" showstereotype="1" y="-2550.56" text="cam2" font="72,9,-1,5,50,0,0,0,0,0" localid="ujU9gxSNM8lbW" pretext="+" role="710" width="105" isinstance="0" posttext="" usefillcolor="1" fillcolor="none" xmi.id="uGimGhIWUKLR8" autoresize="1" height="41"/>
</assocwidget>
<assocwidget linecolor="#ff0000" indexa="1" usesdiagramfillcolor="1" widgetbid="uQ6I6JzsO2HGl" indexb="1" linewidth="0" seqnum="" textcolor="none" usesdiagramusefillcolor="1" totalcounta="2" totalcountb="2" widgetaid="u3PKuOJQ3ZHmI" font="Sans Serif,9,-1,0,50,0,0,0,0,0" visibilityA="0" visibilityB="0" localid="uWggVIxe3GZNE" usefillcolor="1" fillcolor="none" changeabilityA="900" xmi.id="uNQiElSTPK1AA" changeabilityB="900" autoresize="1" type="510">
<linepath layout="Direct">
<startpoint startx="-2850.47" starty="-2164.51"/>
<endpoint endx="-1509.78" endy="-2006.53"/>
</linepath>
<floatingtext linecolor="#ff0000" usesdiagramfillcolor="1" linewidth="0" textcolor="none" usesdiagramusefillcolor="1" x="-1561.72" showstereotype="1" y="-2100.06" text="pi" font="72,9,-1,5,50,0,0,0,0,0" localid="uO7bJj9sB7sEU" pretext="+" role="710" width="52" isinstance="0" posttext="" usefillcolor="1" fillcolor="none" xmi.id="uXGjJenEF0FiS" autoresize="1" height="41"/>
</assocwidget>
<assocwidget linecolor="#ff0000" indexa="1" usesdiagramfillcolor="1" widgetbid="ue6uiThNgNDFB" indexb="1" linewidth="0" seqnum="" textcolor="none" usesdiagramusefillcolor="1" totalcounta="2" totalcountb="2" widgetaid="u3PKuOJQ3ZHmI" font="Sans Serif,9,-1,0,50,0,0,0,0,0" visibilityA="0" visibilityB="0" localid="uWF902NAP0FHZ" usefillcolor="1" fillcolor="none" changeabilityA="900" xmi.id="u0Xj0X088euUT" changeabilityB="900" autoresize="1" type="510">
<linepath layout="Direct">
<startpoint startx="-2850.47" starty="-2164.51"/>
<endpoint endx="-2063.77" endy="-1889.28"/>
</linepath>
<floatingtext linecolor="#ff0000" usesdiagramfillcolor="1" linewidth="0" textcolor="none" usesdiagramusefillcolor="1" x="-2128.62" showstereotype="1" y="-1965.22" text="img1" font="72,9,-1,5,50,0,0,0,0,0" localid="uOMvz8c4uRmGs" pretext="+" role="710" width="96" isinstance="0" posttext="" usefillcolor="1" fillcolor="none" xmi.id="uFM8WPUy8YUJe" autoresize="1" height="41"/>
</assocwidget>
<assocwidget linecolor="#ff0000" indexa="1" usesdiagramfillcolor="1" widgetbid="uR5ObfNSeeXhB" indexb="1" linewidth="0" seqnum="" textcolor="none" usesdiagramusefillcolor="1" totalcounta="2" totalcountb="2" widgetaid="u3PKuOJQ3ZHmI" font="Sans Serif,9,-1,0,50,0,0,0,0,0" visibilityA="0" visibilityB="0" localid="uvi1ERjnvIdui" usefillcolor="1" fillcolor="none" changeabilityA="900" xmi.id="u8MCZU4xbMiEg" changeabilityB="900" autoresize="1" type="510">
<linepath layout="Direct">
<startpoint startx="-3405.75" starty="-2164.51"/>
<endpoint endx="-3405.75" endy="-1919.14"/>
</linepath>
<floatingtext linecolor="#ff0000" usesdiagramfillcolor="1" linewidth="0" textcolor="none" usesdiagramusefillcolor="1" x="-3431.56" showstereotype="1" y="-1948.35" text="cfg" font="72,9,-1,5,50,0,0,0,0,0" localid="uCHDbxjsh1bsC" pretext="+" role="710" width="70" isinstance="0" posttext="" usefillcolor="1" fillcolor="none" xmi.id="uQLoGPY6Djzz9" autoresize="1" height="41"/>
</assocwidget>
<assocwidget linecolor="#ff0000" indexa="1" usesdiagramfillcolor="1" widgetbid="ue6uiThNgNDFB" indexb="1" linewidth="0" seqnum="" textcolor="none" usesdiagramusefillcolor="1" totalcounta="2" totalcountb="2" widgetaid="u3PKuOJQ3ZHmI" font="Sans Serif,9,-1,0,50,0,0,0,0,0" visibilityA="0" visibilityB="0" localid="uzpvQtxSCtgeV" usefillcolor="1" fillcolor="none" changeabilityA="900" xmi.id="ut9nKlwYYnVoi" changeabilityB="900" autoresize="1" type="510">
<linepath layout="Direct">
<startpoint startx="-2850.47" starty="-2164.51"/>
<endpoint endx="-2063.77" endy="-1889.28"/>
</linepath>
<floatingtext linecolor="#ff0000" usesdiagramfillcolor="1" linewidth="0" textcolor="none" usesdiagramusefillcolor="1" x="-2088.67" showstereotype="1" y="-1924.33" text="img2" font="72,9,-1,5,50,0,0,0,0,0" localid="uSYoXgQc0mKdm" pretext="+" role="710" width="96" isinstance="0" posttext="" usefillcolor="1" fillcolor="none" xmi.id="uPhsv6q2hu9Yj" autoresize="1" height="41"/>
</assocwidget>
<assocwidget indexa="1" linecolor="#ff0000" usesdiagramfillcolor="1" widgetbid="uoU85LGuFdMDB" indexb="1" linewidth="0" seqnum="" textcolor="none" usesdiagramusefillcolor="1" totalcounta="2" totalcountb="2" widgetaid="u3PKuOJQ3ZHmI" font="Sans Serif,9,-1,0,50,0,0,0,0,0" localid="uOI7vRjBvKnLk" usefillcolor="1" fillcolor="none" xmi.id="uDfVM5g16KwFK" autoresize="1" type="512">
<linepath layout="Direct">
<startpoint startx="-2850.47" starty="-2775.09"/>
<endpoint endx="-2183.46" endy="-2775.09"/>
</linepath>
</assocwidget>
<assocwidget indexa="1" linecolor="#ff0000" usesdiagramfillcolor="1" widgetbid="ufQnO4lKJJOqQ" indexb="1" linewidth="0" seqnum="" textcolor="none" usesdiagramusefillcolor="1" totalcounta="2" totalcountb="2" widgetaid="u3PKuOJQ3ZHmI" font="Sans Serif,9,-1,0,50,0,0,0,0,0" localid="una43IhIvazKX" usefillcolor="1" fillcolor="none" xmi.id="uRA8xnAP8hPLu" autoresize="1" type="502">
<linepath layout="Direct">
<startpoint startx="-3559.47" starty="-3245.21"/>
<endpoint endx="-3807.14" endy="-3245.21"/>
</linepath>
</assocwidget>
<assocwidget indexa="1" linecolor="#ff0000" usesdiagramfillcolor="1" widgetbid="uwl3mL4D79Yo7" indexb="1" linewidth="0" seqnum="" textcolor="#000000" usesdiagramusefillcolor="1" totalcounta="2" totalcountb="2" widgetaid="uGAAftKX0LKPe" font="Sans Serif,9,-1,0,50,0,0,0,0,0" localid="uBENDymZQ0MI1" usefillcolor="1" fillcolor="none" xmi.id="u5CgnNl5HfULt" autoresize="1" type="502">
<linepath layout="Direct">
<startpoint startx="-2977.38" starty="-3956.45"/>
<endpoint endx="-3216.42" endy="-3557.69"/>
</linepath>
<floatingtext linecolor="#ff0000" usesdiagramfillcolor="1" linewidth="0" textcolor="none" usesdiagramusefillcolor="1" x="-3171.05" showstereotype="1" y="-3767.11" text="Implementation" font="72,9,-1,5,50,0,0,0,0,0" localid="u5yFRsYIQ4iyc" pretext="" role="703" width="229" isinstance="0" posttext="" usefillcolor="1" fillcolor="none" xmi.id="uSecDXMnXusVA" autoresize="1" height="41"/>
</assocwidget>
<assocwidget linecolor="#ff0000" indexa="1" usesdiagramfillcolor="1" widgetbid="uzwE2u8G0m86m" indexb="1" linewidth="0" seqnum="" textcolor="#000000" usesdiagramusefillcolor="1" totalcounta="2" totalcountb="2" widgetaid="u3PKuOJQ3ZHmI" font="72,9,-1,5,50,0,0,0,0,0" visibilityA="1" visibilityB="1" localid="ugwL6g39jCwkk" usefillcolor="1" fillcolor="none" changeabilityA="900" xmi.id="udPNNn2PcNrHC" changeabilityB="900" autoresize="1" type="510">
<linepath layout="Direct">
<startpoint startx="-2850.47" starty="-2164.51"/>
<endpoint endx="-2845.17" endy="-1878.72"/>
</linepath>
</assocwidget>
<assocwidget linecolor="#ff0000" indexa="1" usesdiagramfillcolor="1" widgetbid="uzwE2u8G0m86m" indexb="1" linewidth="0" seqnum="" textcolor="none" usesdiagramusefillcolor="1" totalcounta="2" totalcountb="2" widgetaid="u3PKuOJQ3ZHmI" font="72,9,-1,5,50,0,0,0,0,0" visibilityA="1" visibilityB="1" localid="ulJ357gClgDK6" usefillcolor="1" fillcolor="none" changeabilityA="900" xmi.id="udPNNn2PcNrHC" changeabilityB="900" autoresize="1" type="510">
<linepath layout="Direct">
<startpoint startx="-2850.47" starty="-2164.51"/>
<endpoint endx="-2845.17" endy="-1878.72"/>
</linepath>
<floatingtext linecolor="#ff0000" usesdiagramfillcolor="1" linewidth="0" textcolor="none" usesdiagramusefillcolor="1" x="-2923.17" showstereotype="1" y="-1897.72" text="new_attribute" font="72,9,-1,5,50,0,0,0,0,0" localid="uxEZb3z81dW5j" pretext="-" role="710" width="213" isinstance="0" posttext="" usefillcolor="1" fillcolor="none" xmi.id="uVHM5Pfq2IOj1" autoresize="1" height="41"/>
</assocwidget>
</associations>
</diagram>
</diagrams>
</XMI.extension>
</UML:Model>
<UML:Model visibility="public" isSpecification="false" namespace="m1" isAbstract="false" isLeaf="false" isRoot="false" xmi.id="Use_Case_View" name="Use Case View">
<UML:Namespace.ownedElement/>
</UML:Model>
<UML:Model visibility="public" isSpecification="false" namespace="m1" isAbstract="false" isLeaf="false" isRoot="false" xmi.id="Component_View" name="Component View">
<UML:Namespace.ownedElement/>
</UML:Model>
<UML:Model visibility="public" isSpecification="false" namespace="m1" isAbstract="false" isLeaf="false" isRoot="false" xmi.id="Deployment_View" name="Deployment View">
<UML:Namespace.ownedElement/>
</UML:Model>
<UML:Model visibility="public" isSpecification="false" namespace="m1" isAbstract="false" isLeaf="false" isRoot="false" xmi.id="Entity_Relationship_Model" name="Entity Relationship Model">
<UML:Namespace.ownedElement/>
</UML:Model>
</UML:Namespace.ownedElement>
</UML:Model>
</XMI.content>
<XMI.extensions xmi.extender="umbrello">
<docsettings viewid="uh50sSCS4d9CW" uniqueid="uWf2ft6JklEaE" documentation=""/>
<listview>
<listitem open="1" type="800" id="Views">
<listitem open="1" type="821" id="Component_View"/>
<listitem open="1" type="827" id="Deployment_View"/>
<listitem open="1" type="836" id="Entity_Relationship_Model"/>
<listitem open="1" type="801" id="Logical_View">
<listitem open="0" type="813" id="uaevmzQNQgKmj"/>
<listitem open="1" type="813" id="u3PKuOJQ3ZHmI">
<listitem open="0" type="815" id="uO2fh3ZIpaQ0Q"/>
<listitem open="0" type="815" id="u7NJmYxPdLR2E"/>
<listitem open="0" type="814" id="uymjTPSDmdslG"/>
<listitem open="0" type="814" id="uoLKqxEi69MUl"/>
<listitem open="0" type="814" id="ufIN4B2QLPgEQ"/>
<listitem open="0" type="814" id="uL2g1QxGDWG8P"/>
<listitem open="0" type="814" id="u8MCZU4xbMiEg"/>
<listitem open="0" type="815" id="uLDln74tq9szY"/>
<listitem open="0" type="814" id="uRi1y0XyJalyj"/>
<listitem open="0" type="814" id="uyapd5AklqW2M"/>
<listitem open="0" type="814" id="uVSsIBojVxely"/>
<listitem open="0" type="814" id="upZaWekqlJGOu"/>
<listitem open="0" type="814" id="u6fxkTP89Z1qe"/>
<listitem open="0" type="815" id="uPdYwEtgwUr7M"/>
<listitem open="0" type="814" id="uQktcNU0aviX8"/>
<listitem open="0" type="814" id="u0Xj0X088euUT"/>
<listitem open="0" type="814" id="uA0ZTyryE5xWB"/>
<listitem open="0" type="814" id="ut9nKlwYYnVoi"/>
<listitem open="0" type="814" id="uu9ijKRtgAZ41"/>
<listitem open="0" type="815" id="uiXEv7E9KGfsR"/>
<listitem open="0" type="814" id="uaUz0wgB6JyLj"/>
<listitem open="0" type="814" id="udPNNn2PcNrHC"/>
<listitem open="0" type="814" id="uwUwxWUudCOHB"/>
<listitem open="0" type="814" id="uT8SNBGCApzWW"/>
<listitem open="0" type="814" id="ufYv515nwSPqj"/>
<listitem open="0" type="814" id="uNQiElSTPK1AA"/>
<listitem open="0" type="815" id="ueC1huFz5YPpg"/>
<listitem open="0" type="815" id="uUPdS1ZrMGgcF"/>
<listitem open="0" type="815" id="uO5FndUBgdMJz"/>
<listitem open="0" type="815" id="u0Lt9TbmnJ6LX"/>
<listitem open="0" type="815" id="upkwhWC3xlCWC"/>
<listitem open="0" type="815" id="u1XeTdWi0QBh4"/>
<listitem open="0" type="815" id="u2xVDrZOlSOdH"/>
<listitem open="0" type="815" id="uLePJCLiyq259"/>
<listitem open="0" type="815" id="uluEZIogNmfGj"/>
<listitem open="0" type="815" id="uOGEHt4i016lY"/>
<listitem open="0" type="815" id="uyQDSKZoMq9BF"/>
<listitem open="0" type="814" id="uGDIcSUE3EGw1"/>
<listitem open="0" type="814" id="uDb3JwPxTrhjI"/>
</listitem>
<listitem open="1" type="813" id="u3OjgIBqJBgyn"/>
<listitem open="0" type="813" id="uThfpCkW5KNLv">
<listitem open="0" type="814" id="uw6PICFVwOCba"/>
<listitem open="0" type="815" id="uMaStZQf88d7V"/>
<listitem open="0" type="815" id="uAvdIrTdIHqSR"/>
<listitem open="0" type="815" id="uFB9wjh3mxa6V"/>
</listitem>
<listitem open="1" type="813" id="ufQnO4lKJJOqQ">
<listitem open="0" type="815" id="uFKAtmpK3IMid"/>
<listitem open="0" type="815" id="u5cgflHGyG5Wy"/>
<listitem open="0" type="815" id="uI4dZ7OZj6Dck"/>
<listitem open="0" type="815" id="uM6ZHX24fBYDF"/>
<listitem open="0" type="815" id="uyfsEqdxKqZoC"/>
<listitem open="0" type="815" id="udlBYvFW4qCAE"/>
<listitem open="0" type="815" id="uNJuqryn6sANI"/>
<listitem open="0" type="815" id="uUdzbcmeA8Gxb"/>
<listitem open="0" type="815" id="unKiaC72rI4rD"/>
</listitem>
<listitem open="0" type="807" id="uh50sSCS4d9CW" label="class diagram"/>
<listitem open="0" type="813" id="u9nAYpyG3aSi9"/>
<listitem open="0" type="813" id="uCW0AMheY8JMc"/>
<listitem open="1" type="830" id="Datatypes">
<listitem open="0" type="829" id="uzncWu1t5XAqV"/>
<listitem open="0" type="829" id="uWD0LCe31Qe6z"/>
<listitem open="0" type="829" id="uivFEqo1zOYsW"/>
<listitem open="0" type="829" id="ut3U2TtHTDMqm"/>
<listitem open="0" type="829" id="uC8n0yHzYaFtW"/>
<listitem open="0" type="829" id="ue6uiThNgNDFB"/>
<listitem open="0" type="829" id="uSN9tVhGt4JeL"/>
<listitem open="0" type="829" id="usVn8H52hL2Et"/>
<listitem open="0" type="829" id="uhStEw218vtpA"/>
<listitem open="0" type="829" id="unEKbNBpRDYxe"/>
<listitem open="0" type="829" id="uQ6I6JzsO2HGl"/>
<listitem open="0" type="829" id="uWZbdMIa5lsbb"/>
<listitem open="0" type="829" id="uXwBFpyqikx4b"/>
<listitem open="0" type="829" id="uvnmQ4VudFICo"/>
<listitem open="0" type="829" id="uYBWUNRPEoBmu"/>
<listitem open="0" type="829" id="uPqdLsqMUsaYG"/>
<listitem open="0" type="829" id="uwf3jLNyYyCZ7"/>
<listitem open="0" type="829" id="ufgglRaUHqAMn"/>
<listitem open="0" type="829" id="urdHVFlCDEbzy"/>
<listitem open="0" type="829" id="uqO664Buw0Nbg"/>
<listitem open="0" type="829" id="uAbtVeD2yGn1P"/>
<listitem open="0" type="829" id="uUeccgrWVodPs"/>
<listitem open="0" type="829" id="uNS8ituxzmJ7d"/>
<listitem open="0" type="829" id="uDw2wLV7OL4hx"/>
<listitem open="0" type="829" id="u5k9vnaRqpOn5"/>
</listitem>
<listitem open="0" type="813" id="uR5ObfNSeeXhB">
<listitem open="0" type="814" id="urtrPGD8N67ak"/>
<listitem open="0" type="815" id="uTwlbMfaiRTi5"/>
<listitem open="0" type="815" id="uLNiFClGsFzcu"/>
<listitem open="0" type="814" id="uwm6wS4amN83t"/>
<listitem open="0" type="814" id="uWE1lJn5ztJt4"/>
<listitem open="0" type="814" id="uslwnDGlFhEKl"/>
<listitem open="0" type="814" id="usgU8DKlARM7s"/>
<listitem open="0" type="814" id="uMboyjzkx7nU5"/>
<listitem open="0" type="814" id="uVyfgg9vCFyLF"/>
<listitem open="0" type="814" id="ufH4qMUyirg5i"/>
<listitem open="0" type="814" id="upDIZFxX7bZ6O"/>
<listitem open="0" type="814" id="u5DfWhjMibNqp"/>
<listitem open="0" type="815" id="u7FWGOooMzqnV"/>
<listitem open="0" type="815" id="u2NFAHYdxh8lI"/>
<listitem open="0" type="815" id="uf6RsnKhtZkhd"/>
<listitem open="0" type="815" id="uSGnhkrHFPLJe"/>
<listitem open="0" type="815" id="uh9lxiqqZvb4t"/>
<listitem open="0" type="815" id="usn7OXmHFZ0V5"/>
<listitem open="0" type="815" id="ufBtk9B5e6vcY"/>
<listitem open="0" type="815" id="uxNf4PYxgZFeP"/>
<listitem open="0" type="815" id="uFBKNmVkJwXAg"/>
<listitem open="0" type="815" id="uU4wEZvpnz3fQ"/>
<listitem open="0" type="815" id="uiAextWuFOiac"/>
<listitem open="0" type="815" id="uRKZ3442mgMnu"/>
<listitem open="0" type="815" id="ukY6qrpCL8Nlr"/>
<listitem open="0" type="815" id="uI1i2o8Gc0RLs"/>
<listitem open="0" type="815" id="uXvrVLeazI8eQ"/>
<listitem open="0" type="815" id="uMpUhKnowbroP"/>
<listitem open="0" type="814" id="u2yY3Af7pGO0b"/>
<listitem open="0" type="814" id="u6UhY8WirooGu"/>
<listitem open="0" type="814" id="uLZD8gmVseX6H"/>
<listitem open="0" type="814" id="uD9jHFWDVmkVF"/>
<listitem open="0" type="814" id="uyCGecgUq18Mv"/>
<listitem open="0" type="815" id="uxEFottbVdn4G"/>
<listitem open="0" type="815" id="ulqCSHhgfAqqc"/>
<listitem open="0" type="815" id="ufBYXnRBO8t2W"/>
<listitem open="0" type="815" id="up4FwTAhBBJRk"/>
</listitem>
<listitem open="0" type="831" id="u77iMFNAED177">
<listitem open="0" type="839" id="ugzTrox5Tq0Bz"/>
<listitem open="0" type="839" id="ulr7ywjKJFqKv"/>
</listitem>
<listitem open="0" type="813" id="u7TjMMyLbs3BP"/>
<listitem open="0" type="813" id="uoU85LGuFdMDB">
<listitem open="0" type="814" id="u9QQxhPVspW9l"/>
<listitem open="0" type="815" id="uKEDftAItizrV"/>
<listitem open="0" type="815" id="uzCdyUze9yX4J"/>
<listitem open="0" type="814" id="uaBNa9sS4Wa2g"/>
<listitem open="0" type="814" id="uOerTnEHIUx5L"/>
<listitem open="0" type="814" id="ulkS8k9zQQLaM"/>
<listitem open="0" type="815" id="uQPa9LvXEplCu"/>
<listitem open="0" type="815" id="uxtY80lwBi7zq"/>
<listitem open="0" type="815" id="uhMBGrq7UyGN8"/>
<listitem open="0" type="815" id="u0EBanNhgMx7X"/>
<listitem open="0" type="814" id="uuN4wnwIerM4o"/>
<listitem open="0" type="814" id="u1YkYmMVBAI19"/>
<listitem open="0" type="814" id="unkWUm0O7ndTU"/>
<listitem open="0" type="815" id="u2UVDXa9OTsSR"/>
<listitem open="0" type="814" id="u04xfse750aW6"/>
<listitem open="0" type="814" id="uRNXMUhfRINIT"/>
<listitem open="0" type="815" id="ui70uJ6muM7Xa"/>
<listitem open="0" type="814" id="ux3CpaWDBIAvf"/>
<listitem open="0" type="814" id="uwU3hjHwmL2Wh"/>
</listitem>
<listitem open="0" type="813" id="u6VqpQtja46wn">
<listitem open="0" type="815" id="ufEvOSrA0kcSt"/>
<listitem open="0" type="814" id="udBKRc4AmGjrD"/>
<listitem open="0" type="815" id="uyztga7pvel5D"/>
<listitem open="0" type="814" id="usGshqCwmzGc4"/>
<listitem open="0" type="815" id="uP33bLmUpvU3x"/>
<listitem open="0" type="814" id="u4WUp2PwsYM4i"/>
<listitem open="0" type="814" id="uqsXpacajVP7j"/>
</listitem>
<listitem open="1" type="813" id="uGAAftKX0LKPe">
<listitem open="0" type="815" id="uqIrOThJN3Ivp"/>
<listitem open="0" type="815" id="uUBAUdS6srw6D"/>
<listitem open="0" type="815" id="uZaEMGpppzuKF"/>
</listitem>
<listitem open="0" type="813" id="uuxstJ2dy9vxT"/>
<listitem open="0" type="817" id="uwl3mL4D79Yo7">
<listitem open="0" type="815" id="u5IbfNv3J3Z8v"/>
</listitem>
<listitem open="0" type="813" id="uzwE2u8G0m86m">
<listitem open="0" type="814" id="udLhM9iyVlr22"/>
<listitem open="0" type="815" id="uKEsgcOL0LOOO"/>
</listitem>
</listitem>
<listitem open="1" type="802" id="Use_Case_View"/>
</listitem>
</listview>
<codegeneration>
<codegenerator language="C++"/>
</codegeneration>
</XMI.extensions>
</XMI>

View file

@ -1,2 +1,2 @@
#! /usr/bin/env sh
sudo java -jar discoTesting-4.3.6.jar 2>/dev/null
sudo java -jar discoTesting-4.3.7.jar 2>/dev/null

View file

@ -25,7 +25,7 @@ public class Cli
/**
* Complete build version number
*/
private static final String version = "4.3.6";
private static final String version = "4.3.7";
/**
* Currently saved iteration count.
@ -58,7 +58,7 @@ public class Cli
/**
* Number of options currently available in the camera configuration sub-menu.
*/
private static final int cameraMenuOptionCount = 6;
private static final int cameraMenuOptionCount = 7;
/**
* Lock object, used for temporary interruption of {@link #runTests()}
@ -85,7 +85,7 @@ public class Cli
int userInput = 0;
ErrorLogging.logError("Calibrating motor movement. This may take several minutes...");
ErrorLogging.logError("Calibrating motor movement. ");
ErrorLogging.logError("The piston will fire momentarily when the motor calibration is complete.");
MovementFacade.pressButton();
@ -191,6 +191,7 @@ public class Cli
*/
private static void printHelp()
{
println("\n\n");
println("========================================");
println("Explanations:");
println("----------------------------------------");
@ -261,6 +262,7 @@ public class Cli
*/
private static void printCameraMenu(List<String> cameraList)
{
println("\n\n");
println("Available cameras to configure:");
println("------------------------------------");
for(int index = 0; index < cameraList.size(); index++)
@ -278,6 +280,7 @@ public class Cli
*/
private static void printSerialMenu(List<String> cameraList)
{
println("\n\n");
println("Available serial numbers to set:");
println("------------------------------------");
for(int index = 0; index < cameraList.size(); index++)
@ -299,6 +302,7 @@ public class Cli
*/
private static void printActiveToggleMenu(List<String> cameraList)
{
println("\n\n");
println("Available cameras to toggle:");
println("------------------------------------");
for(int index = 0; index < cameraList.size(); index++)
@ -337,10 +341,52 @@ public class Cli
println("3. Change Threshold Value");
println("4. Toggle crop");
println("5. Toggle threshold");
println("6. Exit");
println("6. Help");
println("7. Exit");
println("====================================");
}
/**
* Pre-defined menu for printing camera configuration options
*/
private static void printCameraConfigHelpMenu()
{
println("\n\n");
println("============================================================");
println("Camera Config Menu options:");
println("------------------------------------------------------------");
println("1. Change Crop Region:");
println("\tChange where to crop the image down to.");
println("\tThis crop should only include the numbers");
println("\ton the screen of the DUT, and not include");
println("\tthe battery symbol, the degree symbol, or");
println("\tany other additional items on the screen.");
println("2. Change Composite Frame Count:");
println("\tChange the number of images to stack on top of each other.");
println("\tA higher number here can compensate slightly for low ");
println("\tthreshold value.");
println("");
println("3. Change Threshold Value:");
println("\tChange the threshold point used on the image.");
println("\tValid numbers range from 0 to 255.");
println("\tA higher number will make more of the image black.");
println("\tA lower number will make more of the image white.");
println("");
println("4. Toggle crop:");
println("\tTurn off cropping for the preview.");
println("");
println("5. Toggle threshold:");
println("\tTurn off thesholding for the preview.");
println("");
println("6. Help:");
println("\tShow this menu");
println("");
println("7. Exit:");
println("\t Exit to the previous menu to pick another camera");
println("============================================================");
println("Press enter to continue...");
}
/**
* Sub-function used to configure cameras.
*/
@ -404,6 +450,10 @@ public class Cli
modifiedProperty = ConfigProperties.THRESHOLD;
break;
case 6:
printCameraConfigHelpMenu();
inputScanner.nextLine();
break;
case 7:
modifiedProperty = ConfigProperties.PRIME;
break;
default:

View file

@ -9,9 +9,6 @@ import com.pi4j.io.gpio.digital.DigitalOutput;
import com.pi4j.io.gpio.digital.DigitalOutputConfigBuilder;
import com.pi4j.io.gpio.digital.DigitalState;
import com.pi4j.io.gpio.digital.PullResistance;
import com.pi4j.io.pwm.Pwm;
import com.pi4j.io.pwm.PwmConfigBuilder;
import com.pi4j.io.pwm.PwmType;
/**
* Facade for all movement of the fixture.
@ -36,30 +33,9 @@ public class MovementFacade
private static Thread runSwitchThread;
/**
* Max allowed speed by current fixture design.
* Motor appears to start acting erratically over 192kHz.
* Fraction of the total travel time, so the arm won't push through the limit switch.
*/
private static final int MAX_FREQUENCY = 192000;
/**
* Amount of buffer between the found absolute speed, and used speed.
*/
private static final int SPEED_BUFFER = 7500;
/**
* Minimum allowed speed of the fixture arm; also used for reset travels.
*/
private static final int MIN_FREQUENCY = 10000;
/**
* Fraction of the total travel time at speed to start slowing down.
*/
private static final double SLOW_POLL_FACTOR = 3.0 / 4.0;
/**
* Amount to slow down the speed by.
*/
private static final int SPEED_DOWN_FACTOR = 2;
private static final double SLOW_POLL_FACTOR = 0.95;
/**
* Amount of distance to travel.
@ -68,17 +44,6 @@ public class MovementFacade
*/
private static double TRAVEL_DIST;
/**
* Frequency fed to the PWM pin, which the motor controller converts into movement speed.
*/
private static int FREQUENCY = MIN_FREQUENCY;
/**
* PWM Duty Cycle.
* Does not affect motor speed; necessary for PWM setup.
*/
private static final int DUTY_CYCLE = 50;
//PWM Addresses
//All addresses are in BCM format.
@ -97,11 +62,6 @@ public class MovementFacade
*/
private static final int PISTON_ADDR = 25;
/**
* PWM pin address.
*/
private static final int PWM_PIN_ADDR = 12;
/**
* Input pin address for the run switch.
*/
@ -122,11 +82,6 @@ public class MovementFacade
*/
private static final int POLL_WAIT = 10;
/**
* Multiply the time-out value by this value to get the number of polls to make.
*/
private static final int TIME_CONVERSION = 1000 / POLL_WAIT;
//Pi GPIO pin objects
/**
@ -177,12 +132,6 @@ public class MovementFacade
*/
private static DigitalOutput pistonActivate;
/**
* PWM pin object.
* Never used, but needs to be initialised to get GPIO to work properly.
*/
private static Pwm pwm;
/**
* {@link Pi4J} API interaction object.
*/
@ -224,60 +173,9 @@ public class MovementFacade
motorDirection = outputBuilder("motorDirection", "Motor Direction", MOTOR_DIRECTION_ADDR);
pistonActivate = outputBuilder("piston" , "Piston Activate", PISTON_ADDR);
pwm = pwmBuilder("pwm","PWM Pin",PWM_PIN_ADDR);
pwm.on(DUTY_CYCLE, FREQUENCY);
calibrate();
findDistance();
}
/**
* Builder function for PWM pins.
*
* @param id ID of the new PWM pin.
* @param name Name of the new PWM pin.
* @param address BCM address of the PWM pin.
*
* @return newly created PWM pin object.
*/
private static Pwm pwmBuilder(String id, String name, int address)
{
PwmConfigBuilder configBuilder;
switch (address)
{
//The following pins allow for hardware PWM support.
case 12:
case 13:
case 18:
case 19:
case 40:
case 41:
case 45:
case 52:
case 53:
configBuilder = Pwm.newConfigBuilder(pi4j)
.id(id)
.name(name)
.address(address)
.pwmType(PwmType.HARDWARE)
.frequency(FREQUENCY)
.provider("pigpio-pwm")
.initial(1)
.shutdown(0);
break;
//Any pin not listed above must be software PWM controlled.
default:
configBuilder = Pwm.newConfigBuilder(pi4j)
.id(id)
.name(name)
.address(address)
.pwmType(PwmType.SOFTWARE)
.frequency(FREQUENCY)
.provider("pigpio-pwm")
.initial(1)
.shutdown(0);
}
return pi4j.create(configBuilder);
}
/**
* Builder function for DigitalInput pins.
@ -328,7 +226,6 @@ public class MovementFacade
ErrorLogging.logError("DEBUG: --------------------------------------");
int counter;
ErrorLogging.logError("DEBUG: Setting minimum frequency of PWM...");
pwm.on(DUTY_CYCLE, MIN_FREQUENCY);
if(upperLimit.isHigh())
{
ErrorLogging.logError("DEBUG: Motor at highest point! Lowering to reset.");
@ -362,22 +259,6 @@ public class MovementFacade
return counter;
}
/**
* Used to programmatically determine the motor's max speed.
*/
private static void calibrate()
{
ErrorLogging.logError("Determining distance to limit switches...");
findDistance();
ErrorLogging.logError("Resetting arm to set speed.");
resetArm();
ErrorLogging.logError("Calibrating...");
FREQUENCY = calib(MIN_FREQUENCY, MAX_FREQUENCY, 10000);
ErrorLogging.logError("Calibration complete!");
ErrorLogging.logError("DEBUG: Speed set to " + (FREQUENCY - SPEED_BUFFER));
setFrequency(FREQUENCY - SPEED_BUFFER);
}
/**
* Used to programmatically find the distance between the upper and lower limit switches.
*/
@ -386,7 +267,7 @@ public class MovementFacade
resetArm();
int downTravelCounter = 0;
int upTravelCounter = 0;
pwm.on(DUTY_CYCLE, MIN_FREQUENCY);
//pwm.on(DUTY_CYCLE, MIN_FREQUENCY);
motorDirection.low();
motorEnable.on();
for(downTravelCounter = 0; downTravelCounter < Integer.MAX_VALUE; downTravelCounter++)
@ -401,8 +282,6 @@ public class MovementFacade
motorEnable.off();
if(lowerLimit.isOff()) ErrorLogging.logError("DEBUG: False positive on findDistance down!");
int downTravelDist = downTravelCounter * MIN_FREQUENCY;
ErrorLogging.logError("DEBUG: Down travel distance found to be: " + downTravelDist);
ErrorLogging.logError("DEBUG: Down travel count: " + downTravelCounter);
motorDirection.high();
@ -419,95 +298,10 @@ public class MovementFacade
motorEnable.off();
if(upperLimit.isOff()) ErrorLogging.logError("DEBUG: False positive on findDistance up!");
int upTravelDist = upTravelCounter * MIN_FREQUENCY;
ErrorLogging.logError("DEBUG: Up travel distance found to be: " + upTravelDist);
ErrorLogging.logError("DEBUG: Up travel count: " + downTravelCounter);
if(Math.abs(upTravelCounter - downTravelCounter) > 3)
{
ErrorLogging.logError("DEBUG: Values differ too far to be error. Setting to lower value.");
}
int travelCounter = Math.min(upTravelCounter, downTravelCounter);
TRAVEL_DIST = travelCounter * MIN_FREQUENCY;
}
/**
* Find the max frequency to feed to the motor.
*
* @param start Lowest frequency to check
* @param max Highest frequency to check
* @param iterate How much to iterate by
*
* @return The largest safe value between start and max.
*/
private static int calib(int start, int max, int iterate)
{
for(int i = start; i < max; i+=iterate)
{
if(!setFrequency(i))
{
ErrorLogging.logError("DEBUG: Speed set unsuccessfully! returning " + MIN_FREQUENCY + "...");
return MIN_FREQUENCY;
}
ErrorLogging.logError("DEBUG: Motor travelling down.");
motorDirection.low();
ErrorLogging.logError("DEBUG: Motor Frequency: " + FREQUENCY);
ErrorLogging.logError("DEBUG: Motor calibrate on.");
motorEnable.on();
int TWO_SECONDS = 2 * TIME_CONVERSION;
for(int j = 0; j < TWO_SECONDS; j++)
{
try{ Thread.sleep(POLL_WAIT); } catch(Exception e){ ErrorLogging.logError(e); }
if(lowerLimit.isHigh())
{
ErrorLogging.logError("DEBUG: Breaking loop early!");
break;
}
}
motorEnable.off();
ErrorLogging.logError("DEBUG: Motor calibrate off.");
if(upperLimit.isHigh())
{
ErrorLogging.logError("DEBUG: Motor failed to move! Returning " + (i - iterate));
return i-iterate;
}
else
{
ErrorLogging.logError("DEBUG: Motor moved at speed " + i + ". Checking for errors.");
if(resetArm() < 10)
{
ErrorLogging.logError("DEBUG: Motor failed to move! Returning " + (i - iterate));
return i - iterate;
}
}
}
return max-iterate;
}
/**
* Safely set the speed of the motor and fixture.
*
* @return true if set successfully, else false
*/
private static boolean setFrequency(int newFrequency)
{
boolean output;
if(newFrequency < MIN_FREQUENCY || newFrequency > MAX_FREQUENCY)
{
ErrorLogging.logError("DEBUG: Invalid MovementFacade.setFrequency() value, setting to minfrequency!");
FREQUENCY = MIN_FREQUENCY;
output = false;
}
else
{
FREQUENCY = newFrequency;
output = true;
}
ErrorLogging.logError("DEBUG: Setting frequency to " + FREQUENCY);
pwm.on(DUTY_CYCLE, FREQUENCY);
return output;
TRAVEL_DIST = travelCounter;
}
/**
@ -526,32 +320,22 @@ public class MovementFacade
{
motorDirection.high();
limitSense = upperLimit;
ErrorLogging.logError("Sending fixture up...");
ErrorLogging.logError("DEBUG: Sending fixture up...");
}
else
{
motorDirection.low();
limitSense = lowerLimit;
ErrorLogging.logError("Sending fixture down...");
ErrorLogging.logError("DEBUG: Sending fixture down...");
}
if(limitSense.isHigh()) return FinalState.SAFE;
pwm.on(DUTY_CYCLE, FREQUENCY);
int totalPollCount = (int)(TRAVEL_DIST / FREQUENCY);
int totalPollCount = (int)(TRAVEL_DIST);
int highSpeedPolls = (int)(totalPollCount * SLOW_POLL_FACTOR);
int notHighSpeedPolls = totalPollCount - highSpeedPolls;
int medSpeedPolls = (int)(notHighSpeedPolls * SLOW_POLL_FACTOR);
int lowSpeedPolls = notHighSpeedPolls - medSpeedPolls;
medSpeedPolls *= SPEED_DOWN_FACTOR;
lowSpeedPolls *= 2 * SPEED_DOWN_FACTOR;
ErrorLogging.logError("DEBUG: =============================");
ErrorLogging.logError("DEBUG: Travel time: " + totalPollCount);
ErrorLogging.logError("DEBUG: High speed poll count: " + highSpeedPolls);
ErrorLogging.logError("DEBUG: Medium speed poll count: " + medSpeedPolls);
ErrorLogging.logError("DEBUG: Low speed poll count: " + lowSpeedPolls);
ErrorLogging.logError("DEBUG: =============================");
motorEnable.on();
for(int i = 0; i < highSpeedPolls; i++)
@ -560,53 +344,13 @@ public class MovementFacade
if(limitSense.isOn())
{
motorEnable.off();
ErrorLogging.logError("DEBUG: Motor moved too fast! Stopping motor early.");
ErrorLogging.logError("DEBUG: Breaking high-speed loop and turning off motor!");
ErrorLogging.logError("DEBUG: Iteration count: " + i);
output = FinalState.FAILED;
break;
}
}
if(motorEnable.isOn())
{
output = FinalState.UNSAFE;
pwm.on(DUTY_CYCLE, (FREQUENCY / SPEED_DOWN_FACTOR));
for(int i = 0; i < medSpeedPolls; i++)
{
try{ Thread.sleep(POLL_WAIT); } catch(Exception e){ ErrorLogging.logError(e); }
if(limitSense.isOn())
{
motorEnable.off();
ErrorLogging.logError("DEBUG: Motor only partially slowed down! Stopping motor early.");
ErrorLogging.logError("DEBUG: Breaking medium-speed loop and turning off motor!");
ErrorLogging.logError("DEBUG: Iteration count: " + i);
break;
}
}
}
if(motorEnable.isOn())
{
output = FinalState.SAFE;
pwm.on(DUTY_CYCLE, (FREQUENCY / (2 * SPEED_DOWN_FACTOR)));
for(int i = 0; i < lowSpeedPolls; i++)
{
try{ Thread.sleep(POLL_WAIT); } catch(Exception e){ ErrorLogging.logError(e); }
if(limitSense.isOn())
{
motorEnable.off();
ErrorLogging.logError("DEBUG: Motor slowed down completely, but hit limit switch early.");
ErrorLogging.logError("DEBUG: Breaking low-speed loop and turning off motor!");
ErrorLogging.logError("DEBUG: Iteration count: " + i);
break;
}
}
}
motorEnable.off();
pwm.on(DUTY_CYCLE, FREQUENCY);
output = (limitSense.isOn() ? FinalState.UNSAFE : FinalState.SAFE);
return output;
}

View file

@ -249,6 +249,16 @@ public class OpenCVFacade
{
Mat uncroppedImage = takePicture(cameraName);
Rect roi = selectROI("Pick Crop Location", uncroppedImage);
if(roi.x() == 0 && roi.y() == 0 && roi.width() == 0 && roi.height() == 0)
{
ErrorLogging.logError("Crop error! - Invalid crop selection.");
ErrorLogging.logError("If the crop region did not have a box indicating is location, please restart the program.");
ConfigFacade.setValue(cameraName,ConfigProperties.CROP_X,ConfigProperties.CROP_X.getDefaultValue());
ConfigFacade.setValue(cameraName,ConfigProperties.CROP_Y,ConfigProperties.CROP_Y.getDefaultValue());
ConfigFacade.setValue(cameraName,ConfigProperties.CROP_W,ConfigProperties.CROP_W.getDefaultValue());
ConfigFacade.setValue(cameraName,ConfigProperties.CROP_H,ConfigProperties.CROP_H.getDefaultValue());
return;
}
ConfigFacade.setValue(cameraName,ConfigProperties.CROP_X, roi.x());
ConfigFacade.setValue(cameraName,ConfigProperties.CROP_Y, roi.y());
ConfigFacade.setValue(cameraName,ConfigProperties.CROP_W, roi.width());

144
umlAndStateFlow.xmi Normal file
View file

@ -0,0 +1,144 @@
<?xml version="1.0" encoding="UTF-8"?>
<XMI xmi.version="1.2" timestamp="2023-03-10T15:27:52" verified="false" xmlns:UML="http://schema.omg.org/spec/UML/1.4">
<XMI.header>
<XMI.documentation>
<XMI.exporter>umbrello uml modeller 2.32.3 http://umbrello.kde.org</XMI.exporter>
<XMI.exporterVersion>1.7.3</XMI.exporterVersion>
<XMI.exporterEncoding>UnicodeUTF8</XMI.exporterEncoding>
</XMI.documentation>
<XMI.metamodel xmi.name="UML" xmi.version="1.4" href="UML.xml"/>
</XMI.header>
<XMI.content>
<UML:Model xmi.id="m1" name="UML Model" isSpecification="false" isAbstract="false" isRoot="false" isLeaf="false">
<UML:Namespace.ownedElement>
<UML:Stereotype isSpecification="false" isLeaf="false" isRoot="false" isAbstract="false" xmi.id="folder" name="folder" namespace="m1" visibility="public"/>
<UML:Model isSpecification="false" isLeaf="false" isRoot="false" isAbstract="false" xmi.id="Logical_View" name="Logical View" namespace="m1" visibility="public">
<UML:Namespace.ownedElement>
<UML:Package isSpecification="false" isLeaf="false" isRoot="false" isAbstract="false" xmi.id="Datatypes" name="Datatypes" namespace="Logical_View" visibility="public" stereotype="folder">
<UML:Namespace.ownedElement>
<UML:DataType isSpecification="false" isLeaf="false" isRoot="false" isAbstract="false" xmi.id="uDoWSpaQhZYMj" name="char" namespace="Datatypes" visibility="public"/>
<UML:DataType isSpecification="false" isLeaf="false" isRoot="false" isAbstract="false" xmi.id="u6dG093IE5KRR" name="int" namespace="Datatypes" visibility="public"/>
<UML:DataType isSpecification="false" isLeaf="false" isRoot="false" isAbstract="false" xmi.id="uCO3HE6xCfnkW" name="float" namespace="Datatypes" visibility="public"/>
<UML:DataType isSpecification="false" isLeaf="false" isRoot="false" isAbstract="false" xmi.id="uCrL5Q2hyX5sQ" name="double" namespace="Datatypes" visibility="public"/>
<UML:DataType isSpecification="false" isLeaf="false" isRoot="false" isAbstract="false" xmi.id="ufLcoOmblD5xA" name="bool" namespace="Datatypes" visibility="public" isActive="false"/>
<UML:DataType isSpecification="false" isLeaf="false" isRoot="false" isAbstract="false" xmi.id="uC91Z5I6GvBha" name="string" namespace="Datatypes" visibility="public" isActive="false"/>
<UML:DataType isSpecification="false" isLeaf="false" isRoot="false" isAbstract="false" xmi.id="upfnNUZyNFmjz" name="unsigned char" namespace="Datatypes" visibility="public" isActive="false"/>
<UML:DataType isSpecification="false" isLeaf="false" isRoot="false" isAbstract="false" xmi.id="ugNO2pJM1hFz7" name="signed char" namespace="Datatypes" visibility="public" isActive="false"/>
<UML:DataType isSpecification="false" isLeaf="false" isRoot="false" isAbstract="false" xmi.id="uKCE2OEBE2Raz" name="unsigned int" namespace="Datatypes" visibility="public" isActive="false"/>
<UML:DataType isSpecification="false" isLeaf="false" isRoot="false" isAbstract="false" xmi.id="uzJVMVJLwomgo" name="signed int" namespace="Datatypes" visibility="public" isActive="false"/>
<UML:DataType isSpecification="false" isLeaf="false" isRoot="false" isAbstract="false" xmi.id="uONsxKyOkUqSG" name="short int" namespace="Datatypes" visibility="public" isActive="false"/>
<UML:DataType isSpecification="false" isLeaf="false" isRoot="false" isAbstract="false" xmi.id="ufjpqsbculg16" name="unsigned short int" namespace="Datatypes" visibility="public" isActive="false"/>
<UML:DataType isSpecification="false" isLeaf="false" isRoot="false" isAbstract="false" xmi.id="uByu3v8UDLNuV" name="signed short int" namespace="Datatypes" visibility="public" isActive="false"/>
<UML:DataType isSpecification="false" isLeaf="false" isRoot="false" isAbstract="false" xmi.id="u6DR57G26MnPK" name="long int" namespace="Datatypes" visibility="public" isActive="false"/>
<UML:DataType isSpecification="false" isLeaf="false" isRoot="false" isAbstract="false" xmi.id="uwGdEGKab0jTL" name="signed long int" namespace="Datatypes" visibility="public" isActive="false"/>
<UML:DataType isSpecification="false" isLeaf="false" isRoot="false" isAbstract="false" xmi.id="uFMaK6PVQ2sTp" name="unsigned long int" namespace="Datatypes" visibility="public" isActive="false"/>
<UML:DataType isSpecification="false" isLeaf="false" isRoot="false" isAbstract="false" xmi.id="u12LSDcvfbGFa" name="long double" namespace="Datatypes" visibility="public" isActive="false"/>
<UML:DataType isSpecification="false" isLeaf="false" isRoot="false" isAbstract="false" xmi.id="uXdpgpHjS8pIQ" name="wchar_t" namespace="Datatypes" visibility="public" isActive="false"/>
<UML:DataType isSpecification="false" isLeaf="false" isRoot="false" isAbstract="false" xmi.id="uUFR10GCed46Q" name="boolean" namespace="Datatypes" visibility="public"/>
<UML:DataType isSpecification="false" isLeaf="false" isRoot="false" isAbstract="false" xmi.id="udTQ2y9M1GLg9" name="byte" namespace="Datatypes" visibility="public"/>
<UML:DataType isSpecification="false" isLeaf="false" isRoot="false" isAbstract="false" xmi.id="usyIvFLIaNduc" name="short" namespace="Datatypes" visibility="public"/>
<UML:DataType isSpecification="false" isLeaf="false" isRoot="false" isAbstract="false" xmi.id="uRiiCWnAy5RVe" name="long" namespace="Datatypes" visibility="public"/>
<UML:DataType isSpecification="false" isLeaf="false" isRoot="false" isAbstract="false" xmi.id="uMYRTkE3rxR2B" name="String" namespace="Datatypes" visibility="public"/>
<UML:DataType isSpecification="false" isLeaf="false" isRoot="false" isAbstract="false" xmi.id="uDhbC7HamBUXf" name="Integer" namespace="Datatypes" visibility="public"/>
<UML:DataType isSpecification="false" isLeaf="false" isRoot="false" isAbstract="false" xmi.id="uUBHYF2VTs95m" name="Character" namespace="Datatypes" visibility="public"/>
<UML:DataType isSpecification="false" isLeaf="false" isRoot="false" isAbstract="false" xmi.id="umD3Y5YgpHTL5" name="Boolean" namespace="Datatypes" visibility="public"/>
<UML:DataType isSpecification="false" isLeaf="false" isRoot="false" isAbstract="false" xmi.id="uEXdFpDPOdfpV" name="Float" namespace="Datatypes" visibility="public"/>
<UML:DataType isSpecification="false" isLeaf="false" isRoot="false" isAbstract="false" xmi.id="uQwhrzourTSFc" name="Double" namespace="Datatypes" visibility="public"/>
<UML:DataType isSpecification="false" isLeaf="false" isRoot="false" isAbstract="false" xmi.id="uMX44yrUJSq2Z" name="Byte" namespace="Datatypes" visibility="public"/>
<UML:DataType isSpecification="false" isLeaf="false" isRoot="false" isAbstract="false" xmi.id="ujXLj0TVNtFs1" name="Short" namespace="Datatypes" visibility="public"/>
<UML:DataType isSpecification="false" isLeaf="false" isRoot="false" isAbstract="false" xmi.id="uppdevdmKoAeT" name="Long" namespace="Datatypes" visibility="public"/>
<UML:DataType isSpecification="false" isLeaf="false" isRoot="false" isAbstract="false" xmi.id="uN4zCdvj7rsZz" name="StringBuffer" namespace="Datatypes" visibility="public"/>
<UML:DataType isSpecification="false" isLeaf="false" isRoot="false" isAbstract="false" xmi.id="uBwekzeWX8icG" name="StringBuilder" namespace="Datatypes" visibility="public"/>
<UML:DataType isSpecification="false" isLeaf="false" isRoot="false" isAbstract="false" xmi.id="u8ik9hKNzgKcH" name="Lock" namespace="Datatypes" comment="java.util.concurrent.locks.Lock" visibility="public"/>
</UML:Namespace.ownedElement>
</UML:Package>
</UML:Namespace.ownedElement>
<XMI.extension xmi.extender="umbrello">
<diagrams resolution="96">
<diagram xmi.id="ugFPcmQ7CwNNq" name="class diagram" type="1" documentation="" backgroundcolor="#ffffff" fillcolor="#ffffc0" font="Noto Sans,10,-1,5,50,0,0,0,0,0,Regular" griddotcolor="#f7f7f7" linecolor="#ff0000" linewidth="0" textcolor="#000000" usefillcolor="1" showattribassocs="1" showatts="1" showattsig="1" showops="1" showopsig="1" showpackage="1" showpubliconly="0" showscope="1" showstereotype="2" localid="-1" showgrid="0" snapgrid="0" snapcsgrid="0" snapx="25" snapy="25" zoom="100" canvasheight="0" canvaswidth="0" isopen="1">
<widgets/>
<messages/>
<associations/>
</diagram>
<diagram xmi.id="uucBDfma2hRQg" name="activity diagram" type="6" documentation="" backgroundcolor="#ffffff" fillcolor="#ffffc0" font="Noto Sans,10,-1,5,50,0,0,0,0,0,Regular" griddotcolor="#f7f7f7" linecolor="#ff0000" linewidth="0" textcolor="#000000" usefillcolor="1" showattribassocs="1" showatts="1" showattsig="1" showops="1" showopsig="1" showpackage="1" showpubliconly="0" showscope="1" showstereotype="2" localid="-1" showgrid="0" snapgrid="0" snapcsgrid="0" snapx="25" snapy="25" zoom="100" canvasheight="197" canvaswidth="314" isopen="1">
<widgets>
<objectnodewidget xmi.id="u5M4P5Hfu8Nx0" localid="uoJ4Np3PVy53i" textcolor="#000000" linecolor="#ff0000" linewidth="0" usefillcolor="1" usesdiagramfillcolor="0" usesdiagramusefillcolor="0" fillcolor="#ffffc0" font="Noto Sans,10,-1,5,50,0,0,0,0,0,Regular" autoresize="1" x="-280" y="-70" width="105" height="51" isinstance="0" showstereotype="2" objectnodename="Config File" documentation="" objectnodetype="1" objectnodestate=""/>
<activitywidget xmi.id="uepLzsA8b3T2G" localid="u5XRXcu6W6hx8" textcolor="#000000" linecolor="#ff0000" linewidth="0" usefillcolor="1" usesdiagramfillcolor="0" usesdiagramusefillcolor="0" fillcolor="#ffffc0" font="Noto Sans,10,-1,5,50,0,0,0,0,0,Regular" autoresize="1" x="-474" y="-53" width="106" height="28" isinstance="0" showstereotype="2" activityname="Import Config" documentation="" precondition="" postcondition="" activitytype="1"/>
<activitywidget xmi.id="utaWvp4BKKTSY" localid="u48aLE7dXqRpC" textcolor="#000000" linecolor="#ff0000" linewidth="0" usefillcolor="1" usesdiagramfillcolor="0" usesdiagramusefillcolor="0" fillcolor="#ffffc0" font="Noto Sans,10,-1,5,50,0,0,0,0,0,Regular" autoresize="1" x="-445" y="-147" width="15" height="15" isinstance="0" showstereotype="2" activityname="" documentation="" precondition="" postcondition="" activitytype="0"/>
<activitywidget xmi.id="uekMk1xetI6OX" localid="u5psqOHbbWzXS" textcolor="#000000" linecolor="#ff0000" linewidth="0" usefillcolor="1" usesdiagramfillcolor="0" usesdiagramusefillcolor="0" fillcolor="#ffffc0" font="Noto Sans,10,-1,5,50,0,0,0,0,0,Regular" autoresize="1" x="-489" y="22" width="66" height="28" isinstance="0" showstereotype="2" activityname="Import " documentation="" precondition="" postcondition="" activitytype="1"/>
</widgets>
<messages/>
<associations>
<assocwidget xmi.id="uIDUOcD9iayOo" localid="uJnJaAkE7t8iy" textcolor="none" linecolor="#ff0000" linewidth="0" usefillcolor="1" usesdiagramfillcolor="1" usesdiagramusefillcolor="1" fillcolor="none" font="Noto Sans,10,-1,5,50,0,0,0,0,0,Regular" autoresize="1" seqnum="" type="515" visibilityA="0" visibilityB="0" changeabilityA="900" changeabilityB="900" roleAdoc="" roleBdoc="" documentation="" widgetaid="u5M4P5Hfu8Nx0" widgetbid="uepLzsA8b3T2G" indexa="1" totalcounta="2" indexb="1" totalcountb="2">
<linepath layout="Direct">
<startpoint startx="-280" starty="-39"/>
<endpoint endx="-368" endy="-39"/>
</linepath>
</assocwidget>
<assocwidget xmi.id="uRLZBkDQTMnLl" localid="umij5ZfkjzWUl" textcolor="none" linecolor="#ff0000" linewidth="0" usefillcolor="1" usesdiagramfillcolor="1" usesdiagramusefillcolor="1" fillcolor="none" font="Noto Sans,10,-1,5,50,0,0,0,0,0,Regular" autoresize="1" seqnum="" type="515" visibilityA="0" visibilityB="0" changeabilityA="900" changeabilityB="900" roleAdoc="" roleBdoc="" documentation="" widgetaid="utaWvp4BKKTSY" widgetbid="uepLzsA8b3T2G" indexa="1" totalcounta="2" indexb="1" totalcountb="2">
<linepath layout="Direct">
<startpoint startx="-445" starty="-132"/>
<endpoint endx="-445" endy="-53"/>
</linepath>
</assocwidget>
</associations>
</diagram>
</diagrams>
</XMI.extension>
</UML:Model>
<UML:Model isSpecification="false" isLeaf="false" isRoot="false" isAbstract="false" xmi.id="Use_Case_View" name="Use Case View" namespace="m1" visibility="public">
<UML:Namespace.ownedElement/>
</UML:Model>
<UML:Model isSpecification="false" isLeaf="false" isRoot="false" isAbstract="false" xmi.id="Component_View" name="Component View" namespace="m1" visibility="public">
<UML:Namespace.ownedElement/>
</UML:Model>
<UML:Model isSpecification="false" isLeaf="false" isRoot="false" isAbstract="false" xmi.id="Deployment_View" name="Deployment View" namespace="m1" visibility="public">
<UML:Namespace.ownedElement/>
</UML:Model>
<UML:Model isSpecification="false" isLeaf="false" isRoot="false" isAbstract="false" xmi.id="Entity_Relationship_Model" name="Entity Relationship Model" namespace="m1" visibility="public">
<UML:Namespace.ownedElement/>
</UML:Model>
</UML:Namespace.ownedElement>
</UML:Model>
</XMI.content>
<XMI.extensions xmi.extender="umbrello">
<docsettings viewid="uucBDfma2hRQg" documentation="" uniqueid="u5psqOHbbWzXS"/>
<listview>
<listitem id="Views" type="800" open="1">
<listitem id="Component_View" type="821" open="1"/>
<listitem id="Deployment_View" type="827" open="1"/>
<listitem id="Entity_Relationship_Model" type="836" open="1"/>
<listitem id="Logical_View" type="801" open="1">
<listitem id="uucBDfma2hRQg" type="809" label="activity diagram" open="0"/>
<listitem id="ugFPcmQ7CwNNq" type="807" label="class diagram" open="0"/>
<listitem id="Datatypes" type="830" open="0">
<listitem id="uUFR10GCed46Q" type="829" open="1"/>
<listitem id="umD3Y5YgpHTL5" type="829" open="1"/>
<listitem id="udTQ2y9M1GLg9" type="829" open="1"/>
<listitem id="uMX44yrUJSq2Z" type="829" open="1"/>
<listitem id="uDoWSpaQhZYMj" type="829" open="1"/>
<listitem id="uUBHYF2VTs95m" type="829" open="1"/>
<listitem id="uCrL5Q2hyX5sQ" type="829" open="1"/>
<listitem id="uQwhrzourTSFc" type="829" open="1"/>
<listitem id="uCO3HE6xCfnkW" type="829" open="1"/>
<listitem id="uEXdFpDPOdfpV" type="829" open="1"/>
<listitem id="u6dG093IE5KRR" type="829" open="1"/>
<listitem id="uDhbC7HamBUXf" type="829" open="1"/>
<listitem id="u8ik9hKNzgKcH" type="829" open="1"/>
<listitem id="uRiiCWnAy5RVe" type="829" open="1"/>
<listitem id="uppdevdmKoAeT" type="829" open="1"/>
<listitem id="usyIvFLIaNduc" type="829" open="1"/>
<listitem id="ujXLj0TVNtFs1" type="829" open="1"/>
<listitem id="uMYRTkE3rxR2B" type="829" open="1"/>
<listitem id="uN4zCdvj7rsZz" type="829" open="1"/>
<listitem id="uBwekzeWX8icG" type="829" open="1"/>
</listitem>
</listitem>
<listitem id="Use_Case_View" type="802" open="1"/>
</listitem>
</listview>
<codegeneration>
<codegenerator language="Java"/>
</codegeneration>
</XMI.extensions>
</XMI>