Initial commit
Some checks failed
Gradle Build / build (push) Has been cancelled

This commit is contained in:
CaiXiang
2024-11-30 18:36:13 +08:00
commit aa56926258
2134 changed files with 232943 additions and 0 deletions

View File

@@ -0,0 +1,16 @@
// SPDX-FileCopyrightText: The openTCS Authors
// SPDX-License-Identifier: MIT
apply from: "${rootDir}/gradle/java-project.gradle"
apply from: "${rootDir}/gradle/java-codequality.gradle"
apply from: "${rootDir}/gradle/guice-project.gradle"
apply from: "${rootDir}/gradle/publishing-java.gradle"
dependencies {
api project(':opentcs-api-injection')
api project(':opentcs-common')
}
task release {
dependsOn build
}

View File

@@ -0,0 +1,40 @@
netbeans.org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.wrapAnnotationArgs=WRAP_IF_LONG
netbeans.org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.alignMultilineMethodParams=true
netbeans.org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.wrapAfterDotInChainedMethodCalls=false
netbeans.org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.alignMultilineDisjunctiveCatchTypes=true
netbeans.org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.alignMultilineFor=true
netbeans.org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.alignMultilineImplements=true
netbeans.org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.wrapFor=WRAP_IF_LONG
netbeans.org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.sortMembersByVisibility=true
netbeans.org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.visibilityOrder=PUBLIC;PROTECTED;DEFAULT;PRIVATE
netbeans.org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.placeFinallyOnNewLine=true
netbeans.org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.wrapMethodParams=WRAP_IF_LONG
netbeans.org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.enable-indent=true
netbeans.org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.alignMultilineArrayInit=true
netbeans.org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.alignMultilineCallArgs=true
netbeans.org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.wrapDisjunctiveCatchTypes=WRAP_IF_LONG
netbeans.org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.keepGettersAndSettersTogether=true
netbeans.org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.wrapExtendsImplementsList=WRAP_ALWAYS
netbeans.org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.wrapThrowsKeyword=WRAP_ALWAYS
netbeans.org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.wrapExtendsImplementsKeyword=WRAP_ALWAYS
netbeans.org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.classMembersOrder=STATIC FIELD;FIELD;STATIC_INIT;CONSTRUCTOR;INSTANCE_INIT;STATIC METHOD;METHOD;STATIC CLASS;CLASS
netbeans.org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.wrapEnumConstants=WRAP_ALWAYS
netbeans.org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.wrapCommentText=false
netbeans.org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.wrapThrowsList=WRAP_IF_LONG
netbeans.org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.wrapAssert=WRAP_IF_LONG
netbeans.org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.importGroupsOrder=*
netbeans.org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.continuationIndentSize=4
netbeans.org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.placeElseOnNewLine=true
netbeans.org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.placeCatchOnNewLine=true
netbeans.org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.alignMultilineAnnotationArgs=true
netbeans.org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.alignMultilineTryResources=true
netbeans.org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.preserveNewLinesInComments=true
netbeans.org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.alignMultilineParenthesized=true
netbeans.org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.alignMultilineThrows=true
netbeans.org-netbeans-modules-editor-indent.CodeStyle.project.text-line-wrap=none
netbeans.org-netbeans-modules-editor-indent.CodeStyle.project.indent-shift-width=2
netbeans.org-netbeans-modules-editor-indent.CodeStyle.project.spaces-per-tab=2
netbeans.org-netbeans-modules-editor-indent.CodeStyle.project.tab-size=2
netbeans.org-netbeans-modules-editor-indent.CodeStyle.project.text-limit-width=100
netbeans.org-netbeans-modules-editor-indent.CodeStyle.project.expand-tabs=true
netbeans.org-netbeans-modules-editor-indent.CodeStyle.usedProfile=project

View File

@@ -0,0 +1,44 @@
// SPDX-FileCopyrightText: The openTCS Authors
// SPDX-License-Identifier: MIT
package org.opentcs.guing.plugins.panels.loadgenerator;
import org.opentcs.customizations.plantoverview.PlantOverviewInjectionModule;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* Configures the load generator panel.
*/
public class LoadGeneratorPanelModule
extends
PlantOverviewInjectionModule {
/**
* This class's logger.
*/
private static final Logger LOG = LoggerFactory.getLogger(LoadGeneratorPanelModule.class);
/**
* Creates a new instance.
*/
public LoadGeneratorPanelModule() {
}
@Override
protected void configure() {
ContinuousLoadPanelConfiguration configuration
= getConfigBindingProvider().get(
ContinuousLoadPanelConfiguration.PREFIX,
ContinuousLoadPanelConfiguration.class
);
if (!configuration.enable()) {
LOG.info("Continuous load panel disabled by configuration.");
return;
}
// tag::documentation_createPluginPanelModule[]
pluggablePanelFactoryBinder().addBinding().to(ContinuousLoadPanelFactory.class);
// end::documentation_createPluginPanelModule[]
}
}

View File

@@ -0,0 +1,4 @@
# SPDX-FileCopyrightText: The openTCS Authors
# SPDX-License-Identifier: MIT
org.opentcs.guing.plugins.panels.loadgenerator.LoadGeneratorPanelModule

View File

@@ -0,0 +1,724 @@
<?xml version="1.0" encoding="UTF-8" ?>
<Form version="1.6" maxVersion="1.7" type="org.netbeans.modules.form.forminfo.JPanelFormInfo">
<NonVisualComponents>
<Component class="javax.swing.ButtonGroup" name="orderSpecButtonGroup">
</Component>
<Component class="javax.swing.ButtonGroup" name="triggerButtonGroup">
</Component>
<Component class="javax.swing.JComboBox" name="operationTypesComboBox">
<Properties>
<Property name="model" type="javax.swing.ComboBoxModel" editor="org.netbeans.modules.form.editors2.ComboBoxModelEditor">
<StringArray count="0"/>
</Property>
<Property name="toolTipText" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="i18n/org/opentcs/plantoverview/loadGeneratorPanel/Bundle.properties" key="continuousLoadPanel.comboBox_operationTypes.tooltipText" replaceFormat="java.util.ResourceBundle.getBundle(&quot;{bundleNameSlashes}&quot;).getString(&quot;{key}&quot;)"/>
</Property>
</Properties>
<AuxValues>
<AuxValue name="JavaCodeGenerator_TypeParameters" type="java.lang.String" value="&lt;String&gt;"/>
</AuxValues>
</Component>
<Component class="javax.swing.JComboBox" name="locationsComboBox">
<Properties>
<Property name="model" type="javax.swing.ComboBoxModel" editor="org.netbeans.modules.form.editors2.ComboBoxModelEditor">
<StringArray count="0"/>
</Property>
<Property name="toolTipText" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="i18n/org/opentcs/plantoverview/loadGeneratorPanel/Bundle.properties" key="continuousLoadPanel.comboBox_locations.tooltipText" replaceFormat="java.util.ResourceBundle.getBundle(&quot;{bundleNameSlashes}&quot;).getString(&quot;{key}&quot;)"/>
</Property>
</Properties>
<Events>
<EventHandler event="itemStateChanged" listener="java.awt.event.ItemListener" parameters="java.awt.event.ItemEvent" handler="locationsComboBoxItemStateChanged"/>
</Events>
<AuxValues>
<AuxValue name="JavaCodeGenerator_CreateCodePost" type="java.lang.String" value="locationsComboBox.setRenderer(new LocationComboBoxRenderer());"/>
<AuxValue name="JavaCodeGenerator_TypeParameters" type="java.lang.String" value="&lt;TCSObjectReference&lt;Location&gt;&gt;"/>
</AuxValues>
</Component>
<Component class="javax.swing.JFileChooser" name="fileChooser">
<Properties>
<Property name="fileFilter" type="javax.swing.filechooser.FileFilter" editor="org.netbeans.modules.form.RADConnectionPropertyEditor">
<Connection code="new FileNameExtensionFilter(&quot;*.xml&quot;, &quot;xml&quot;)" type="code"/>
</Property>
</Properties>
</Component>
</NonVisualComponents>
<Properties>
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
<Dimension value="[520, 700]"/>
</Property>
</Properties>
<AccessibilityProperties>
<Property name="AccessibleContext.accessibleName" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="i18n/org/opentcs/plantoverview/loadGeneratorPanel/Bundle.properties" key="continuousLoadPanel.accessibleName" replaceFormat="java.util.ResourceBundle.getBundle(&quot;{bundleNameSlashes}&quot;).getString(&quot;{key}&quot;)"/>
</Property>
</AccessibilityProperties>
<AuxValues>
<AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="0"/>
<AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/>
<AuxValue name="FormSettings_formBundle" type="java.lang.String" value="org/opentcs/genericclient/panels/loadgenerator/Bundle"/>
<AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/>
<AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="false"/>
<AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="false"/>
<AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="1"/>
<AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/>
<AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/>
<AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/>
<AuxValue name="designerSize" type="java.awt.Dimension" value="-84,-19,0,5,115,114,0,18,106,97,118,97,46,97,119,116,46,68,105,109,101,110,115,105,111,110,65,-114,-39,-41,-84,95,68,20,2,0,2,73,0,6,104,101,105,103,104,116,73,0,5,119,105,100,116,104,120,112,0,0,1,-8,0,0,2,44"/>
</AuxValues>
<Layout class="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout"/>
<SubComponents>
<Container class="javax.swing.JPanel" name="triggerPanel">
<Properties>
<Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor">
<Border info="org.netbeans.modules.form.compat2.border.TitledBorderInfo">
<TitledBorder title="Trigger for generating orders">
<ResourceString PropertyName="titleX" bundle="i18n/org/opentcs/plantoverview/loadGeneratorPanel/Bundle.properties" key="continuousLoadPanel.panel_generateTrigger.border.title" replaceFormat="java.util.ResourceBundle.getBundle(&quot;{bundleNameSlashes}&quot;).getString(&quot;{key}&quot;)"/>
</TitledBorder>
</Border>
</Property>
</Properties>
<Constraints>
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
<GridBagConstraints gridX="0" gridY="0" gridWidth="1" gridHeight="1" fill="2" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="0" insetsBottom="0" insetsRight="0" anchor="18" weightX="1.0" weightY="0.0"/>
</Constraint>
</Constraints>
<Layout class="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout"/>
<SubComponents>
<Component class="javax.swing.JRadioButton" name="thresholdTriggerRadioButton">
<Properties>
<Property name="buttonGroup" type="javax.swing.ButtonGroup" editor="org.netbeans.modules.form.RADComponent$ButtonGroupPropertyEditor">
<ComponentRef name="triggerButtonGroup"/>
</Property>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="i18n/org/opentcs/plantoverview/loadGeneratorPanel/Bundle.properties" key="continuousLoadPanel.radioButton_triggerByOrderThreshold.text" replaceFormat="java.util.ResourceBundle.getBundle(&quot;{bundleNameSlashes}&quot;).getString(&quot;{key}&quot;)"/>
</Property>
</Properties>
<Constraints>
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
<GridBagConstraints gridX="0" gridY="1" gridWidth="1" gridHeight="1" fill="2" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="0" insetsBottom="0" insetsRight="0" anchor="10" weightX="0.0" weightY="0.0"/>
</Constraint>
</Constraints>
</Component>
<Component class="javax.swing.JSpinner" name="thresholdSpinner">
<Properties>
<Property name="model" type="javax.swing.SpinnerModel" editor="org.netbeans.modules.form.editors2.SpinnerModelEditor">
<SpinnerModel initial="10" maximum="100" minimum="0" numberType="java.lang.Integer" stepSize="1" type="number"/>
</Property>
</Properties>
<Constraints>
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
<GridBagConstraints gridX="1" gridY="1" gridWidth="1" gridHeight="1" fill="2" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="3" insetsBottom="0" insetsRight="0" anchor="10" weightX="0.0" weightY="0.0"/>
</Constraint>
</Constraints>
</Component>
<Component class="javax.swing.JLabel" name="thresholdOrdersLbl">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="i18n/org/opentcs/plantoverview/loadGeneratorPanel/Bundle.properties" key="continuousLoadPanel.label_unitOrdersToBeProcessed.text" replaceFormat="java.util.ResourceBundle.getBundle(&quot;{bundleNameSlashes}&quot;).getString(&quot;{key}&quot;)"/>
</Property>
</Properties>
<Constraints>
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
<GridBagConstraints gridX="2" gridY="1" gridWidth="1" gridHeight="1" fill="2" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="3" insetsBottom="0" insetsRight="0" anchor="10" weightX="0.0" weightY="0.0"/>
</Constraint>
</Constraints>
</Component>
<Component class="javax.swing.JLabel" name="fillingLbl">
<Constraints>
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
<GridBagConstraints gridX="3" gridY="1" gridWidth="1" gridHeight="1" fill="1" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="0" insetsBottom="0" insetsRight="0" anchor="10" weightX="1.0" weightY="0.0"/>
</Constraint>
</Constraints>
</Component>
<Component class="javax.swing.JRadioButton" name="timerTriggerRadioButton">
<Properties>
<Property name="buttonGroup" type="javax.swing.ButtonGroup" editor="org.netbeans.modules.form.RADComponent$ButtonGroupPropertyEditor">
<ComponentRef name="triggerButtonGroup"/>
</Property>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="i18n/org/opentcs/plantoverview/loadGeneratorPanel/Bundle.properties" key="continuousLoadPanel.radioButton_triggerAfterTimeout.text" replaceFormat="java.util.ResourceBundle.getBundle(&quot;{bundleNameSlashes}&quot;).getString(&quot;{key}&quot;)"/>
</Property>
</Properties>
<Constraints>
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
<GridBagConstraints gridX="0" gridY="2" gridWidth="1" gridHeight="1" fill="2" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="0" insetsBottom="0" insetsRight="0" anchor="10" weightX="0.0" weightY="0.0"/>
</Constraint>
</Constraints>
</Component>
<Component class="javax.swing.JSpinner" name="timerSpinner">
<Properties>
<Property name="model" type="javax.swing.SpinnerModel" editor="org.netbeans.modules.form.editors2.SpinnerModelEditor">
<SpinnerModel initial="60" maximum="3600" minimum="1" numberType="java.lang.Integer" stepSize="1" type="number"/>
</Property>
</Properties>
<Constraints>
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
<GridBagConstraints gridX="1" gridY="2" gridWidth="1" gridHeight="1" fill="2" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="3" insetsBottom="0" insetsRight="0" anchor="10" weightX="0.0" weightY="0.0"/>
</Constraint>
</Constraints>
</Component>
<Component class="javax.swing.JLabel" name="timerSecondsLbl">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="i18n/org/opentcs/plantoverview/loadGeneratorPanel/Bundle.properties" key="continuousLoadPanel.label_unitSeconds.text" replaceFormat="java.util.ResourceBundle.getBundle(&quot;{bundleNameSlashes}&quot;).getString(&quot;{key}&quot;)"/>
</Property>
</Properties>
<Constraints>
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
<GridBagConstraints gridX="2" gridY="2" gridWidth="1" gridHeight="1" fill="2" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="3" insetsBottom="0" insetsRight="0" anchor="10" weightX="0.0" weightY="0.0"/>
</Constraint>
</Constraints>
</Component>
<Component class="javax.swing.JRadioButton" name="singleTriggerRadioButton">
<Properties>
<Property name="buttonGroup" type="javax.swing.ButtonGroup" editor="org.netbeans.modules.form.RADComponent$ButtonGroupPropertyEditor">
<ComponentRef name="triggerButtonGroup"/>
</Property>
<Property name="selected" type="boolean" value="true"/>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="i18n/org/opentcs/plantoverview/loadGeneratorPanel/Bundle.properties" key="continuousLoadPanel.radioButton_triggerOnce.text" replaceFormat="java.util.ResourceBundle.getBundle(&quot;{bundleNameSlashes}&quot;).getString(&quot;{key}&quot;)"/>
</Property>
</Properties>
<Constraints>
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
<GridBagConstraints gridX="0" gridY="0" gridWidth="1" gridHeight="1" fill="2" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="0" insetsBottom="0" insetsRight="0" anchor="10" weightX="0.0" weightY="0.0"/>
</Constraint>
</Constraints>
</Component>
</SubComponents>
</Container>
<Container class="javax.swing.JPanel" name="orderProfilePanel">
<Properties>
<Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor">
<Border info="org.netbeans.modules.form.compat2.border.TitledBorderInfo">
<TitledBorder title="Order profile">
<ResourceString PropertyName="titleX" bundle="i18n/org/opentcs/plantoverview/loadGeneratorPanel/Bundle.properties" key="continuousLoadPanel.panel_orderProfile.border.title" replaceFormat="java.util.ResourceBundle.getBundle(&quot;{bundleNameSlashes}&quot;).getString(&quot;{key}&quot;)"/>
</TitledBorder>
</Border>
</Property>
</Properties>
<Constraints>
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
<GridBagConstraints gridX="0" gridY="1" gridWidth="1" gridHeight="1" fill="1" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="0" insetsBottom="0" insetsRight="0" anchor="18" weightX="0.0" weightY="0.0"/>
</Constraint>
</Constraints>
<Layout class="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout"/>
<SubComponents>
<Container class="javax.swing.JPanel" name="randomOrderSpecPanel">
<Constraints>
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
<GridBagConstraints gridX="-1" gridY="-1" gridWidth="1" gridHeight="1" fill="2" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="0" insetsBottom="0" insetsRight="0" anchor="10" weightX="1.0" weightY="0.0"/>
</Constraint>
</Constraints>
<Layout class="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout"/>
<SubComponents>
<Component class="javax.swing.JRadioButton" name="randomOrderSpecButton">
<Properties>
<Property name="buttonGroup" type="javax.swing.ButtonGroup" editor="org.netbeans.modules.form.RADComponent$ButtonGroupPropertyEditor">
<ComponentRef name="orderSpecButtonGroup"/>
</Property>
<Property name="selected" type="boolean" value="true"/>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="i18n/org/opentcs/plantoverview/loadGeneratorPanel/Bundle.properties" key="continuousLoadPanel.radioButton_createOrdersRandomly.text" replaceFormat="java.util.ResourceBundle.getBundle(&quot;{bundleNameSlashes}&quot;).getString(&quot;{key}&quot;)"/>
</Property>
</Properties>
<Events>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="randomOrderSpecButtonActionPerformed"/>
</Events>
<Constraints>
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
<GridBagConstraints gridX="0" gridY="0" gridWidth="1" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="0" insetsBottom="0" insetsRight="0" anchor="10" weightX="0.0" weightY="0.0"/>
</Constraint>
</Constraints>
</Component>
<Component class="javax.swing.JSpinner" name="randomOrderCountSpinner">
<Properties>
<Property name="model" type="javax.swing.SpinnerModel" editor="org.netbeans.modules.form.editors2.SpinnerModelEditor">
<SpinnerModel initial="7" maximum="100" minimum="1" numberType="java.lang.Integer" stepSize="1" type="number"/>
</Property>
</Properties>
<Constraints>
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
<GridBagConstraints gridX="-1" gridY="-1" gridWidth="1" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="3" insetsBottom="0" insetsRight="0" anchor="10" weightX="0.0" weightY="0.0"/>
</Constraint>
</Constraints>
</Component>
<Component class="javax.swing.JLabel" name="randomOrderCountLbl">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="i18n/org/opentcs/plantoverview/loadGeneratorPanel/Bundle.properties" key="continuousLoadPanel.label_unitOrdersAtATime.text" replaceFormat="java.util.ResourceBundle.getBundle(&quot;{bundleNameSlashes}&quot;).getString(&quot;{key}&quot;)"/>
</Property>
</Properties>
<Constraints>
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
<GridBagConstraints gridX="-1" gridY="-1" gridWidth="1" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="3" insetsBottom="0" insetsRight="0" anchor="10" weightX="0.0" weightY="0.0"/>
</Constraint>
</Constraints>
</Component>
<Component class="javax.swing.JLabel" name="fillingLbl3">
<Constraints>
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
<GridBagConstraints gridX="5" gridY="0" gridWidth="1" gridHeight="1" fill="1" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="0" insetsBottom="0" insetsRight="0" anchor="10" weightX="1.0" weightY="0.0"/>
</Constraint>
</Constraints>
</Component>
<Component class="javax.swing.JSpinner" name="randomOrderSizeSpinner">
<Properties>
<Property name="model" type="javax.swing.SpinnerModel" editor="org.netbeans.modules.form.editors2.SpinnerModelEditor">
<SpinnerModel initial="2" maximum="10" minimum="1" numberType="java.lang.Integer" stepSize="1" type="number"/>
</Property>
</Properties>
<Constraints>
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
<GridBagConstraints gridX="3" gridY="0" gridWidth="1" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="3" insetsBottom="0" insetsRight="0" anchor="10" weightX="0.0" weightY="0.0"/>
</Constraint>
</Constraints>
</Component>
<Component class="javax.swing.JLabel" name="randomOrderSizeLbl">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="i18n/org/opentcs/plantoverview/loadGeneratorPanel/Bundle.properties" key="continuousLoadPanel.label_unitDriveOrdersPerOrder.text" replaceFormat="java.util.ResourceBundle.getBundle(&quot;{bundleNameSlashes}&quot;).getString(&quot;{key}&quot;)"/>
</Property>
</Properties>
<Constraints>
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
<GridBagConstraints gridX="4" gridY="0" gridWidth="1" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="3" insetsBottom="0" insetsRight="0" anchor="10" weightX="0.0" weightY="0.0"/>
</Constraint>
</Constraints>
</Component>
</SubComponents>
</Container>
<Container class="javax.swing.JPanel" name="explicitOrderSpecPanel">
<Constraints>
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
<GridBagConstraints gridX="0" gridY="1" gridWidth="1" gridHeight="1" fill="2" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="0" insetsBottom="0" insetsRight="0" anchor="10" weightX="0.0" weightY="0.0"/>
</Constraint>
</Constraints>
<Layout class="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout"/>
<SubComponents>
<Component class="javax.swing.JRadioButton" name="explicitOrderSpecButton">
<Properties>
<Property name="buttonGroup" type="javax.swing.ButtonGroup" editor="org.netbeans.modules.form.RADComponent$ButtonGroupPropertyEditor">
<ComponentRef name="orderSpecButtonGroup"/>
</Property>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="i18n/org/opentcs/plantoverview/loadGeneratorPanel/Bundle.properties" key="continuousLoadPanel.radioButton_createOrdersAccordingDefinition.text" replaceFormat="java.util.ResourceBundle.getBundle(&quot;{bundleNameSlashes}&quot;).getString(&quot;{key}&quot;)"/>
</Property>
</Properties>
<Events>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="explicitOrderSpecButtonActionPerformed"/>
</Events>
<Constraints>
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
<GridBagConstraints gridX="0" gridY="0" gridWidth="1" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="0" insetsBottom="0" insetsRight="0" anchor="10" weightX="0.0" weightY="0.0"/>
</Constraint>
</Constraints>
</Component>
<Component class="javax.swing.JLabel" name="fillingLbl4">
<Constraints>
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
<GridBagConstraints gridX="-1" gridY="-1" gridWidth="1" gridHeight="1" fill="1" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="0" insetsBottom="0" insetsRight="0" anchor="10" weightX="1.0" weightY="0.0"/>
</Constraint>
</Constraints>
</Component>
</SubComponents>
</Container>
</SubComponents>
</Container>
<Container class="javax.swing.JPanel" name="orderGenPanel">
<Properties>
<Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor">
<Border info="org.netbeans.modules.form.compat2.border.TitledBorderInfo">
<TitledBorder title="Order generation">
<ResourceString PropertyName="titleX" bundle="i18n/org/opentcs/plantoverview/loadGeneratorPanel/Bundle.properties" key="continuousLoadPanel.panel_orderGeneration.border.title" replaceFormat="java.util.ResourceBundle.getBundle(&quot;{bundleNameSlashes}&quot;).getString(&quot;{key}&quot;)"/>
</TitledBorder>
</Border>
</Property>
</Properties>
<Constraints>
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
<GridBagConstraints gridX="0" gridY="3" gridWidth="1" gridHeight="1" fill="1" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="0" insetsBottom="0" insetsRight="0" anchor="18" weightX="0.0" weightY="0.0"/>
</Constraint>
</Constraints>
<Layout class="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout"/>
<SubComponents>
<Component class="javax.swing.JCheckBox" name="orderGenChkBox">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="i18n/org/opentcs/plantoverview/loadGeneratorPanel/Bundle.properties" key="continuousLoadPanel.checkBox_enableOrderGeneration.text" replaceFormat="java.util.ResourceBundle.getBundle(&quot;{bundleNameSlashes}&quot;).getString(&quot;{key}&quot;)"/>
</Property>
</Properties>
<Events>
<EventHandler event="itemStateChanged" listener="java.awt.event.ItemListener" parameters="java.awt.event.ItemEvent" handler="orderGenChkBoxItemStateChanged"/>
</Events>
<Constraints>
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
<GridBagConstraints gridX="0" gridY="0" gridWidth="1" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="0" insetsBottom="0" insetsRight="0" anchor="10" weightX="0.0" weightY="0.0"/>
</Constraint>
</Constraints>
</Component>
<Component class="javax.swing.JLabel" name="fillingLbl5">
<Constraints>
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
<GridBagConstraints gridX="-1" gridY="-1" gridWidth="1" gridHeight="1" fill="1" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="0" insetsBottom="0" insetsRight="0" anchor="10" weightX="1.0" weightY="0.0"/>
</Constraint>
</Constraints>
</Component>
</SubComponents>
</Container>
<Container class="javax.swing.JPanel" name="transportOrderGenPanel">
<Properties>
<Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor">
<Border info="org.netbeans.modules.form.compat2.border.TitledBorderInfo">
<TitledBorder title="Transport order modelling">
<ResourceString PropertyName="titleX" bundle="i18n/org/opentcs/plantoverview/loadGeneratorPanel/Bundle.properties" key="continuousLoadPanel.panel_transportOrderModelling.border.title" replaceFormat="java.util.ResourceBundle.getBundle(&quot;{bundleNameSlashes}&quot;).getString(&quot;{key}&quot;)"/>
</TitledBorder>
</Border>
</Property>
<Property name="enabled" type="boolean" value="false"/>
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
<Dimension value="[1057, 800]"/>
</Property>
</Properties>
<Constraints>
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
<GridBagConstraints gridX="0" gridY="2" gridWidth="1" gridHeight="1" fill="1" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="0" insetsBottom="0" insetsRight="0" anchor="18" weightX="1.0" weightY="1.0"/>
</Constraint>
</Constraints>
<Layout class="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout"/>
<SubComponents>
<Container class="javax.swing.JPanel" name="transportOrdersPanel">
<Properties>
<Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor">
<Border info="org.netbeans.modules.form.compat2.border.TitledBorderInfo">
<TitledBorder title="Transport orders">
<ResourceString PropertyName="titleX" bundle="i18n/org/opentcs/plantoverview/loadGeneratorPanel/Bundle.properties" key="continuousLoadPanel.panel_transportOrders.border.title" replaceFormat="java.util.ResourceBundle.getBundle(&quot;{bundleNameSlashes}&quot;).getString(&quot;{key}&quot;)"/>
</TitledBorder>
</Border>
</Property>
<Property name="enabled" type="boolean" value="false"/>
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
<Dimension value="[568, 452]"/>
</Property>
</Properties>
<Constraints>
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
<GridBagConstraints gridX="0" gridY="0" gridWidth="2" gridHeight="1" fill="1" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="0" insetsBottom="0" insetsRight="0" anchor="10" weightX="1.0" weightY="1.0"/>
</Constraint>
</Constraints>
<Layout class="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout"/>
<SubComponents>
<Container class="javax.swing.JScrollPane" name="jScrollPane2">
<Properties>
<Property name="horizontalScrollBarPolicy" type="int" value="31"/>
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
<Dimension value="[100, 500]"/>
</Property>
</Properties>
<AuxValues>
<AuxValue name="autoScrollPane" type="java.lang.Boolean" value="true"/>
</AuxValues>
<Constraints>
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
<GridBagConstraints gridX="-1" gridY="-1" gridWidth="1" gridHeight="1" fill="1" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="0" insetsBottom="0" insetsRight="0" anchor="10" weightX="1.0" weightY="1.0"/>
</Constraint>
</Constraints>
<Layout class="org.netbeans.modules.form.compat2.layouts.support.JScrollPaneSupportLayout"/>
<SubComponents>
<Component class="javax.swing.JTable" name="toTable">
<Properties>
<Property name="model" type="javax.swing.table.TableModel" editor="org.netbeans.modules.form.RADConnectionPropertyEditor">
<Connection code="new TransportOrderTableModel()" type="code"/>
</Property>
<Property name="columnModel" type="javax.swing.table.TableColumnModel" editor="org.netbeans.modules.form.editors2.TableColumnModelEditor">
<TableColumnModel selectionModel="0"/>
</Property>
<Property name="selectionModel" type="javax.swing.ListSelectionModel" editor="org.netbeans.modules.form.editors2.JTableSelectionModelEditor">
<JTableSelectionModel selectionMode="0"/>
</Property>
<Property name="tableHeader" type="javax.swing.table.JTableHeader" editor="org.netbeans.modules.form.editors2.JTableHeaderEditor">
<TableHeader reorderingAllowed="true" resizingAllowed="true"/>
</Property>
</Properties>
<AuxValues>
<AuxValue name="JavaCodeGenerator_CreateCodePost" type="java.lang.String" value="TOTableSelectionListener listener = new TOTableSelectionListener(toTable);&#xd;toTable.getSelectionModel().addListSelectionListener(listener);"/>
</AuxValues>
</Component>
</SubComponents>
</Container>
<Container class="javax.swing.JPanel" name="transportOrdersActionPanel">
<Constraints>
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
<GridBagConstraints gridX="0" gridY="3" gridWidth="1" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="0" insetsBottom="0" insetsRight="0" anchor="10" weightX="1.0" weightY="0.0"/>
</Constraint>
</Constraints>
<Layout class="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout"/>
<SubComponents>
<Component class="javax.swing.JButton" name="addToTOTableButton">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="i18n/org/opentcs/plantoverview/loadGeneratorPanel/Bundle.properties" key="continuousLoadPanel.button_addTransportOrder.text" replaceFormat="java.util.ResourceBundle.getBundle(&quot;{bundleNameSlashes}&quot;).getString(&quot;{key}&quot;)"/>
</Property>
<Property name="toolTipText" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="i18n/org/opentcs/plantoverview/loadGeneratorPanel/Bundle.properties" key="continuousLoadPanel.button_addTransportOrder.tooltipText" replaceFormat="java.util.ResourceBundle.getBundle(&quot;{bundleNameSlashes}&quot;).getString(&quot;{key}&quot;)"/>
</Property>
<Property name="enabled" type="boolean" value="false"/>
</Properties>
<Events>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="addToTOTableButtonActionPerformed"/>
</Events>
<Constraints>
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
<GridBagConstraints gridX="0" gridY="0" gridWidth="1" gridHeight="1" fill="2" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="0" insetsBottom="0" insetsRight="0" anchor="10" weightX="1.0" weightY="0.0"/>
</Constraint>
</Constraints>
</Component>
<Component class="javax.swing.JButton" name="deleteFromTOTableButton">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="i18n/org/opentcs/plantoverview/loadGeneratorPanel/Bundle.properties" key="continuousLoadPanel.button_deleteSelectedOrder.text" replaceFormat="java.util.ResourceBundle.getBundle(&quot;{bundleNameSlashes}&quot;).getString(&quot;{key}&quot;)"/>
</Property>
<Property name="toolTipText" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="i18n/org/opentcs/plantoverview/loadGeneratorPanel/Bundle.properties" key="continuousLoadPanel.button_deleteSelectedOrder.tooltipText" replaceFormat="java.util.ResourceBundle.getBundle(&quot;{bundleNameSlashes}&quot;).getString(&quot;{key}&quot;)"/>
</Property>
<Property name="enabled" type="boolean" value="false"/>
</Properties>
<Events>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="deleteFromTOTableButtonActionPerformed"/>
</Events>
<Constraints>
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
<GridBagConstraints gridX="1" gridY="0" gridWidth="1" gridHeight="1" fill="2" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="3" insetsBottom="0" insetsRight="0" anchor="10" weightX="1.0" weightY="0.0"/>
</Constraint>
</Constraints>
</Component>
</SubComponents>
</Container>
</SubComponents>
</Container>
<Container class="javax.swing.JTabbedPane" name="jTabbedPane1">
<Properties>
<Property name="enabled" type="boolean" value="false"/>
</Properties>
<AccessibilityProperties>
<Property name="AccessibleContext.accessibleName" type="java.lang.String" value="Drive orders"/>
</AccessibilityProperties>
<Constraints>
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
<GridBagConstraints gridX="0" gridY="1" gridWidth="2" gridHeight="1" fill="1" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="0" insetsBottom="0" insetsRight="0" anchor="10" weightX="1.0" weightY="1.0"/>
</Constraint>
</Constraints>
<Layout class="org.netbeans.modules.form.compat2.layouts.support.JTabbedPaneSupportLayout"/>
<SubComponents>
<Container class="javax.swing.JPanel" name="driveOrdersPanel">
<Properties>
<Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor">
<Border info="org.netbeans.modules.form.compat2.border.TitledBorderInfo">
<TitledBorder title="Drive orders">
<ResourceString PropertyName="titleX" bundle="i18n/org/opentcs/plantoverview/loadGeneratorPanel/Bundle.properties" key="continuousLoadPanel.panel_driveOrders.border.title" replaceFormat="java.util.ResourceBundle.getBundle(&quot;{bundleNameSlashes}&quot;).getString(&quot;{key}&quot;)"/>
</TitledBorder>
</Border>
</Property>
<Property name="enabled" type="boolean" value="false"/>
</Properties>
<Constraints>
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.support.JTabbedPaneSupportLayout" value="org.netbeans.modules.form.compat2.layouts.support.JTabbedPaneSupportLayout$JTabbedPaneConstraintsDescription">
<JTabbedPaneConstraints tabName="Drive orders">
<Property name="tabTitle" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="i18n/org/opentcs/plantoverview/loadGeneratorPanel/Bundle.properties" key="continuousLoadPanel.tab_driveOrders.title" replaceFormat="java.util.ResourceBundle.getBundle(&quot;{bundleNameSlashes}&quot;).getString(&quot;{key}&quot;)"/>
</Property>
</JTabbedPaneConstraints>
</Constraint>
</Constraints>
<Layout class="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout"/>
<SubComponents>
<Container class="javax.swing.JScrollPane" name="driveOrdersScrollPane">
<AuxValues>
<AuxValue name="autoScrollPane" type="java.lang.Boolean" value="true"/>
</AuxValues>
<Constraints>
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
<GridBagConstraints gridX="0" gridY="0" gridWidth="3" gridHeight="1" fill="1" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="0" insetsBottom="0" insetsRight="0" anchor="10" weightX="1.0" weightY="1.0"/>
</Constraint>
</Constraints>
<Layout class="org.netbeans.modules.form.compat2.layouts.support.JScrollPaneSupportLayout"/>
<SubComponents>
<Component class="javax.swing.JTable" name="doTable">
<Properties>
<Property name="model" type="javax.swing.table.TableModel" editor="org.netbeans.modules.form.RADConnectionPropertyEditor">
<Connection code="new DriveOrderTableModel()" type="code"/>
</Property>
<Property name="toolTipText" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/opentcs/remote/genericclient/Bundle.properties" key="continuousLoadPanel.table_driveOrders.tooltipText" replaceFormat="bundle.getString(&quot;{key}&quot;)"/>
</Property>
<Property name="selectionModel" type="javax.swing.ListSelectionModel" editor="org.netbeans.modules.form.editors2.JTableSelectionModelEditor">
<JTableSelectionModel selectionMode="0"/>
</Property>
</Properties>
</Component>
</SubComponents>
</Container>
<Component class="javax.swing.JButton" name="deleteFromDOTableButton">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="i18n/org/opentcs/plantoverview/loadGeneratorPanel/Bundle.properties" key="continuousLoadPanel.button_deleteSelectedDriveOrder.text" replaceFormat="java.util.ResourceBundle.getBundle(&quot;{bundleNameSlashes}&quot;).getString(&quot;{key}&quot;)"/>
</Property>
<Property name="toolTipText" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/opentcs/remote/genericclient/Bundle.properties" key="continuousLoadPanel.button_deleteSelectedDriveOrder.tooltipText" replaceFormat="bundle.getString(&quot;{key}&quot;)"/>
</Property>
<Property name="enabled" type="boolean" value="false"/>
</Properties>
<Events>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="deleteFromDOTableButtonActionPerformed"/>
</Events>
<Constraints>
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
<GridBagConstraints gridX="1" gridY="1" gridWidth="1" gridHeight="1" fill="2" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="0" insetsBottom="0" insetsRight="0" anchor="10" weightX="1.0" weightY="0.0"/>
</Constraint>
</Constraints>
</Component>
<Component class="javax.swing.JButton" name="addDOButton">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="i18n/org/opentcs/plantoverview/loadGeneratorPanel/Bundle.properties" key="continuousLoadPanel.button_addDriveOrder.text" replaceFormat="java.util.ResourceBundle.getBundle(&quot;{bundleNameSlashes}&quot;).getString(&quot;{key}&quot;)"/>
</Property>
<Property name="enabled" type="boolean" value="false"/>
</Properties>
<Events>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="addDOButtonActionPerformed"/>
</Events>
<Constraints>
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
<GridBagConstraints gridX="0" gridY="1" gridWidth="1" gridHeight="1" fill="2" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="0" insetsBottom="0" insetsRight="0" anchor="10" weightX="1.0" weightY="0.0"/>
</Constraint>
</Constraints>
</Component>
</SubComponents>
</Container>
<Container class="javax.swing.JPanel" name="propertyPanel">
<Properties>
<Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor">
<Border info="org.netbeans.modules.form.compat2.border.TitledBorderInfo">
<TitledBorder title="Properties">
<ResourceString PropertyName="titleX" bundle="i18n/org/opentcs/plantoverview/loadGeneratorPanel/Bundle.properties" key="continuousLoadPanel.panel_properties.border.title" replaceFormat="java.util.ResourceBundle.getBundle(&quot;{bundleNameSlashes}&quot;).getString(&quot;{key}&quot;)"/>
</TitledBorder>
</Border>
</Property>
<Property name="enabled" type="boolean" value="false"/>
</Properties>
<Constraints>
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.support.JTabbedPaneSupportLayout" value="org.netbeans.modules.form.compat2.layouts.support.JTabbedPaneSupportLayout$JTabbedPaneConstraintsDescription">
<JTabbedPaneConstraints tabName="Properties">
<Property name="tabTitle" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="i18n/org/opentcs/plantoverview/loadGeneratorPanel/Bundle.properties" key="continuousLoadPanel.tab_properties.title" replaceFormat="java.util.ResourceBundle.getBundle(&quot;{bundleNameSlashes}&quot;).getString(&quot;{key}&quot;)"/>
</Property>
</JTabbedPaneConstraints>
</Constraint>
</Constraints>
<Layout class="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout"/>
<SubComponents>
<Container class="javax.swing.JScrollPane" name="jScrollPane1">
<AuxValues>
<AuxValue name="autoScrollPane" type="java.lang.Boolean" value="true"/>
</AuxValues>
<Constraints>
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
<GridBagConstraints gridX="0" gridY="0" gridWidth="2" gridHeight="1" fill="1" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="0" insetsBottom="0" insetsRight="0" anchor="10" weightX="1.0" weightY="1.0"/>
</Constraint>
</Constraints>
<Layout class="org.netbeans.modules.form.compat2.layouts.support.JScrollPaneSupportLayout"/>
<SubComponents>
<Component class="javax.swing.JTable" name="propertyTable">
</Component>
</SubComponents>
</Container>
<Component class="javax.swing.JButton" name="addPropertyButton">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="i18n/org/opentcs/plantoverview/loadGeneratorPanel/Bundle.properties" key="continuousLoadPanel.button_addProperty.text" replaceFormat="java.util.ResourceBundle.getBundle(&quot;{bundleNameSlashes}&quot;).getString(&quot;{key}&quot;)"/>
</Property>
<Property name="enabled" type="boolean" value="false"/>
</Properties>
<Events>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="addPropertyButtonActionPerformed"/>
</Events>
<Constraints>
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
<GridBagConstraints gridX="0" gridY="1" gridWidth="1" gridHeight="1" fill="2" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="0" insetsBottom="0" insetsRight="0" anchor="10" weightX="1.0" weightY="0.0"/>
</Constraint>
</Constraints>
</Component>
<Component class="javax.swing.JButton" name="removePropertyButton">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="i18n/org/opentcs/plantoverview/loadGeneratorPanel/Bundle.properties" key="continuousLoadPanel.button_removeProperty.text" replaceFormat="java.util.ResourceBundle.getBundle(&quot;{bundleNameSlashes}&quot;).getString(&quot;{key}&quot;)"/>
</Property>
<Property name="enabled" type="boolean" value="false"/>
</Properties>
<Events>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="removePropertyButtonActionPerformed"/>
</Events>
<Constraints>
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
<GridBagConstraints gridX="1" gridY="1" gridWidth="1" gridHeight="1" fill="2" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="0" insetsBottom="0" insetsRight="0" anchor="10" weightX="1.0" weightY="0.0"/>
</Constraint>
</Constraints>
</Component>
</SubComponents>
</Container>
</SubComponents>
</Container>
<Container class="javax.swing.JPanel" name="openSavePanel">
<Constraints>
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
<GridBagConstraints gridX="0" gridY="2" gridWidth="1" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="0" insetsBottom="0" insetsRight="0" anchor="10" weightX="0.0" weightY="0.0"/>
</Constraint>
</Constraints>
<Layout class="org.netbeans.modules.form.compat2.layouts.DesignFlowLayout"/>
<SubComponents>
<Component class="javax.swing.JButton" name="openButton">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="i18n/org/opentcs/plantoverview/loadGeneratorPanel/Bundle.properties" key="continuousLoadPanel.button_open.text" replaceFormat="java.util.ResourceBundle.getBundle(&quot;{bundleNameSlashes}&quot;).getString(&quot;{key}&quot;)"/>
</Property>
<Property name="enabled" type="boolean" value="false"/>
</Properties>
<Events>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="openButtonActionPerformed"/>
</Events>
</Component>
<Component class="javax.swing.JButton" name="saveButton">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="i18n/org/opentcs/plantoverview/loadGeneratorPanel/Bundle.properties" key="continuousLoadPanel.button_save.text" replaceFormat="java.util.ResourceBundle.getBundle(&quot;{bundleNameSlashes}&quot;).getString(&quot;{key}&quot;)"/>
</Property>
<Property name="enabled" type="boolean" value="false"/>
</Properties>
<Events>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="saveButtonActionPerformed"/>
</Events>
</Component>
</SubComponents>
</Container>
</SubComponents>
</Container>
</SubComponents>
</Form>

View File

@@ -0,0 +1,25 @@
// SPDX-FileCopyrightText: The openTCS Authors
// SPDX-License-Identifier: MIT
package org.opentcs.guing.plugins.panels.loadgenerator;
import org.opentcs.configuration.ConfigurationEntry;
import org.opentcs.configuration.ConfigurationPrefix;
/**
* Provides methods to configure the continuous load panel.
*/
@ConfigurationPrefix(ContinuousLoadPanelConfiguration.PREFIX)
public interface ContinuousLoadPanelConfiguration {
/**
* This configuration's prefix.
*/
String PREFIX = "continuousloadpanel";
@ConfigurationEntry(
type = "Boolean",
description = "Whether to enable to register/enable the continuous load panel.",
orderKey = "0_enable"
)
boolean enable();
}

View File

@@ -0,0 +1,59 @@
// SPDX-FileCopyrightText: The openTCS Authors
// SPDX-License-Identifier: MIT
package org.opentcs.guing.plugins.panels.loadgenerator;
import static java.util.Objects.requireNonNull;
import static org.opentcs.guing.plugins.panels.loadgenerator.I18nPlantOverviewPanelLoadGenerator.BUNDLE_PATH;
import jakarta.inject.Inject;
import jakarta.inject.Provider;
import java.util.ResourceBundle;
import org.opentcs.access.Kernel;
import org.opentcs.components.plantoverview.PluggablePanel;
import org.opentcs.components.plantoverview.PluggablePanelFactory;
/**
* Creates load generator panels.
*/
public class ContinuousLoadPanelFactory
implements
PluggablePanelFactory {
/**
* This class's bundle.
*/
private final ResourceBundle bundle = ResourceBundle.getBundle(BUNDLE_PATH);
/**
* A provider for the actual panels.
*/
private final Provider<ContinuousLoadPanel> panelProvider;
/**
* Creates a new instance.
*
* @param panelProvider A provider for the actual panels.
*/
@Inject
public ContinuousLoadPanelFactory(Provider<ContinuousLoadPanel> panelProvider) {
this.panelProvider = requireNonNull(panelProvider, "panelProvider");
}
@Override
public String getPanelDescription() {
return bundle.getString("continuousLoadPanelFactory.panelDescription");
}
@Override
public PluggablePanel createPanel(Kernel.State state) {
if (!providesPanel(state)) {
return null;
}
return panelProvider.get();
}
@Override
public boolean providesPanel(Kernel.State state) {
return Kernel.State.OPERATING.equals(state);
}
}

View File

@@ -0,0 +1,87 @@
// SPDX-FileCopyrightText: The openTCS Authors
// SPDX-License-Identifier: MIT
package org.opentcs.guing.plugins.panels.loadgenerator;
import org.opentcs.data.TCSObjectReference;
import org.opentcs.data.model.Location;
/**
* This class provides the data structure for storing
* and holding the elements typically drive order consists of:
* location and available operation type at this location.
*/
public class DriveOrderStructure {
/**
* The reference to this drive order's location.
*/
private TCSObjectReference<Location> location;
/**
* The available oparation type at the location.
*/
private String vehicleOperation;
/**
* Creates the new instance of DriveOrderStructure.
*
* @param referenceToLocation The reference to the drive order's location.
* @param newVehicleOperation The available operation type at the location.
*/
public DriveOrderStructure(
TCSObjectReference<Location> referenceToLocation,
String newVehicleOperation
) {
if (referenceToLocation == null) {
throw new IllegalArgumentException("location argument is null!");
}
if (newVehicleOperation == null) {
throw new IllegalArgumentException("vehicleOperation argument is null!");
}
location = referenceToLocation;
vehicleOperation = newVehicleOperation;
}
/**
* Creates an empty DriveOrderStructure.
*/
public DriveOrderStructure() {
location = null;
vehicleOperation = null;
}
/**
* Returns a reference to the location.
*
* @return The reference to the location.
*/
public TCSObjectReference<Location> getDriveOrderLocation() {
return this.location;
}
/**
* Sets the location of this order.
*
* @param loc The new location
*/
public void setDriveOrderLocation(TCSObjectReference<Location> loc) {
location = loc;
}
/**
* Sets the vehicle operation of this order.
*
* @param op The new operation
*/
public void setDriveOrderVehicleOperation(String op) {
vehicleOperation = op;
}
/**
* Returns this drive order's operation type.
*
* @return The drive order's operation type.
*/
public String getDriveOrderVehicleOperation() {
return this.vehicleOperation;
}
}

View File

@@ -0,0 +1,198 @@
// SPDX-FileCopyrightText: The openTCS Authors
// SPDX-License-Identifier: MIT
package org.opentcs.guing.plugins.panels.loadgenerator;
import static java.util.Objects.requireNonNull;
import static org.opentcs.guing.plugins.panels.loadgenerator.I18nPlantOverviewPanelLoadGenerator.BUNDLE_PATH;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.ResourceBundle;
import javax.swing.table.AbstractTableModel;
import org.opentcs.data.TCSObjectReference;
import org.opentcs.data.model.Location;
/**
* A table model for drive orders.
*/
class DriveOrderTableModel
extends
AbstractTableModel {
/**
* This classe's bundle.
*/
private final ResourceBundle bundle = ResourceBundle.getBundle(BUNDLE_PATH);
/**
* The column names.
*/
private final String[] columnNames
= new String[]{
bundle.getString(
"driveOrderTableModel.column_location.headerText"
),
bundle.getString(
"driveOrderTableModel.column_operation.headerText"
)
};
/**
* The column classes.
*/
private final Class<?>[] columnClasses
= new Class<?>[]{
TCSObjectReference.class,
String.class
};
/**
* The actual content.
*/
private final List<DriveOrderStructure> driveOrderDataList = new ArrayList<>();
/**
* Creates a new instance.
*
* @param driveOrders The actual list of drive orders.
*/
DriveOrderTableModel(List<DriveOrderStructure> driveOrders) {
requireNonNull(driveOrders, "driveOrders");
for (DriveOrderStructure curDOS : driveOrders) {
driveOrderDataList.add(curDOS);
}
}
/**
* Creates a new instance.
*/
DriveOrderTableModel() {
}
@Override
public int getRowCount() {
return driveOrderDataList.size();
}
@Override
public int getColumnCount() {
return columnNames.length;
}
@Override
public Object getValueAt(int rowIndex, int columnIndex) {
if (rowIndex < 0 || rowIndex >= driveOrderDataList.size()) {
return null;
}
DriveOrderStructure data = driveOrderDataList.get(rowIndex);
if (data == null) {
return null;
}
switch (columnIndex) {
case 0:
if (data.getDriveOrderLocation() == null) {
return null;
}
else {
return data.getDriveOrderLocation().getName();
}
case 1:
return data.getDriveOrderVehicleOperation();
default:
throw new IllegalArgumentException("Invalid columnIndex: " + columnIndex);
}
}
@Override
public String getColumnName(int columnIndex) {
return columnNames[columnIndex];
}
@Override
public Class<?> getColumnClass(int columnIndex) {
return columnClasses[columnIndex];
}
@Override
public boolean isCellEditable(int rowIndex, int columnIndex) {
switch (columnIndex) {
case 0:
return true;
case 1:
return true;
default:
throw new IllegalArgumentException("Invalid columnIndex: " + columnIndex);
}
}
@SuppressWarnings("unchecked")
@Override
public void setValueAt(Object aValue, int rowIndex, int columnIndex) {
if (rowIndex < 0 || rowIndex >= driveOrderDataList.size()) {
return;
}
DriveOrderStructure data = driveOrderDataList.get(rowIndex);
if (aValue == null) {
return;
}
switch (columnIndex) {
case 0:
data.setDriveOrderLocation((TCSObjectReference<Location>) aValue);
break;
case 1:
data.setDriveOrderVehicleOperation((String) aValue);
break;
default:
throw new IllegalArgumentException("Unhandled columnIndex: " + columnIndex);
}
}
/**
* Returns this model's complete content.
*
* @return This model's complete content. The result list is unmodifiable.
*/
public List<DriveOrderStructure> getContent() {
return Collections.unmodifiableList(driveOrderDataList);
}
/**
* Returns the DriveOrderStructure at the given index.
*
* @param row Index which DriveOrderStructure shall be returned
* @return The DriveOrderStructure
*/
public DriveOrderStructure getDataAt(int row) {
if (row < 0 || row >= driveOrderDataList.size()) {
return null;
}
return driveOrderDataList.get(row);
}
/**
* Adds drive order data to the end of the model/list.
*
* @param driveOrder The new drive order data
*/
public void addData(DriveOrderStructure driveOrder) {
requireNonNull(driveOrder, "driveOrder");
driveOrderDataList.add(driveOrder);
fireTableDataChanged();
}
/**
* Removes the DriveOrderStructure at the given index.
* Does nothing if <code>row</code> is not in scope.
*
* @param row Index which DriveOrderStructure shall be removed
*/
public void removeData(int row) {
if (row < 0 || row >= driveOrderDataList.size()) {
return;
}
driveOrderDataList.remove(row);
fireTableDataChanged();
}
}

View File

@@ -0,0 +1,14 @@
// SPDX-FileCopyrightText: The openTCS Authors
// SPDX-License-Identifier: MIT
package org.opentcs.guing.plugins.panels.loadgenerator;
/**
* Defines constants regarding internationalization.
*/
public interface I18nPlantOverviewPanelLoadGenerator {
/**
* The path to the project's resource bundle.
*/
String BUNDLE_PATH = "i18n/org/opentcs/plantoverview/loadGeneratorPanel/Bundle";
}

View File

@@ -0,0 +1,43 @@
// SPDX-FileCopyrightText: The openTCS Authors
// SPDX-License-Identifier: MIT
package org.opentcs.guing.plugins.panels.loadgenerator;
import java.awt.Component;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.ListCellRenderer;
import org.opentcs.data.TCSObjectReference;
import org.opentcs.data.model.Location;
/**
* A combo box renderer for locations.
*/
class LocationComboBoxRenderer
extends
JLabel
implements
ListCellRenderer<TCSObjectReference<Location>> {
/**
* Creates a new instance.
*/
LocationComboBoxRenderer() {
}
@Override
public Component getListCellRendererComponent(
JList<? extends TCSObjectReference<Location>> list,
TCSObjectReference<Location> value,
int index,
boolean isSelected,
boolean cellHasFocus
) {
if (value == null) {
setText("");
}
else {
setText(value.getName());
}
return this;
}
}

View File

@@ -0,0 +1,245 @@
// SPDX-FileCopyrightText: The openTCS Authors
// SPDX-License-Identifier: MIT
package org.opentcs.guing.plugins.panels.loadgenerator;
import static java.util.Objects.requireNonNull;
import static org.opentcs.guing.plugins.panels.loadgenerator.I18nPlantOverviewPanelLoadGenerator.BUNDLE_PATH;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.ResourceBundle;
import javax.swing.table.AbstractTableModel;
/**
* Table model for transport order proerties.
*/
class PropertyTableModel
extends
AbstractTableModel {
/**
* This classe's bundle.
*/
private static final ResourceBundle BUNDLE = ResourceBundle.getBundle(BUNDLE_PATH);
/**
* The column names.
*/
private static final String[] COLUMN_NAMES
= new String[]{
BUNDLE.getString(
"propertyTableModel.column_key.headerText"
),
BUNDLE.getString(
"propertyTableModel.column_value.headerText"
)
};
/**
* The column classes.
*/
private static final Class<?>[] COLUMN_CLASSES
= new Class<?>[]{
String.class,
String.class
};
/**
* The properties we're maintaining.
*/
private List<PropEntry> data = new ArrayList<>();
/**
* Creates a new instance.
*
* @param data The properties.
*/
PropertyTableModel(Map<String, String> data) {
requireNonNull(data, "data");
for (Entry<String, String> entry : data.entrySet()) {
this.data.add(new PropEntry(entry.getKey(), entry.getValue()));
}
}
/**
* Creates a new instance.
*/
PropertyTableModel() {
}
@Override
public int getRowCount() {
return data.size();
}
@Override
public int getColumnCount() {
return COLUMN_NAMES.length;
}
@Override
public Object getValueAt(int rowIndex, int columnIndex) {
if (rowIndex < 0 || rowIndex >= data.size()) {
return null;
}
PropEntry entry = data.get(rowIndex);
switch (columnIndex) {
case 0:
return entry.getKey();
case 1:
return entry.getValue();
default:
throw new IllegalArgumentException("Invalid columnIndex: " + columnIndex);
}
}
@Override
public String getColumnName(int columnIndex) {
return COLUMN_NAMES[columnIndex];
}
@Override
public Class<?> getColumnClass(int columnIndex) {
return COLUMN_CLASSES[columnIndex];
}
@Override
public boolean isCellEditable(int rowIndex, int columnIndex) {
switch (columnIndex) {
case 0:
return true;
case 1:
return true;
default:
throw new IllegalArgumentException("Invalid columnIndex: " + columnIndex);
}
}
@Override
public void setValueAt(Object aValue, int rowIndex, int columnIndex) {
if (rowIndex < 0 || rowIndex >= data.size()) {
return;
}
PropEntry entry = data.get(rowIndex);
if (aValue == null) {
return;
}
switch (columnIndex) {
case 0:
entry.setKey((String) aValue);
break;
case 1:
entry.setValue((String) aValue);
break;
default:
throw new IllegalArgumentException("Unhandled columnIndex: " + columnIndex);
}
}
/**
* Returns this model's complete content.
*
* @return This model's complete content. The result list is unmodifiable.
*/
public List<PropEntry> getList() {
return Collections.unmodifiableList(data);
}
/**
* Adds an entry to the end of the model/list.
*
* @param propEntry The new entry.
*/
public void addData(PropEntry propEntry) {
requireNonNull(propEntry, "propEntry");
data.add(propEntry);
fireTableDataChanged();
}
/**
* Removes the entry at the given index.
* Does nothing if <code>row</code> does not exist.
*
* @param row Index of entry to be removed.
*/
public void removeData(int row) {
if (row < 0 || row >= data.size()) {
return;
}
data.remove(row);
fireTableDataChanged();
}
/**
* A class for editing properties.
*/
public static class PropEntry {
/**
* The key.
*/
private String key = "";
/**
* The value.
*/
private String value = "";
/**
* Creates a new instance.
*/
PropEntry() {
}
/**
* Creates a new PropEntry.
*
* @param key The key
* @param value The value
*/
PropEntry(String key, String value) {
this.key = requireNonNull(key, "key");
this.value = requireNonNull(value, "value");
}
/**
* Returns the key.
*
* @return The key
*/
public String getKey() {
return key;
}
/**
* Sets the key.
*
* @param key The new key
*/
public void setKey(String key) {
this.key = requireNonNull(key, "key");
}
/**
* Returns the value.
*
* @return The value
*/
public String getValue() {
return value;
}
/**
* Sets the value.
*
* @param value The new value
*/
public void setValue(String value) {
this.value = requireNonNull(value, "value");
}
}
}

View File

@@ -0,0 +1,229 @@
// SPDX-FileCopyrightText: The openTCS Authors
// SPDX-License-Identifier: MIT
package org.opentcs.guing.plugins.panels.loadgenerator;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.TreeMap;
import org.opentcs.data.TCSObjectReference;
import org.opentcs.data.model.Vehicle;
import org.opentcs.data.order.DriveOrder;
/**
* <code>TransportOrderData</code> implements functionalities for creating
* and for local storing of xml telegrams.
* The transport/drive oder data is stored in this class.
*/
public class TransportOrderData {
/**
* The new transport order's deadline.
*/
private Deadline deadline = Deadline.PLUS_ONE_HOUR;
/**
* The drive orders the transport order consists of.
*/
private final List<DriveOrderStructure> driveOrders = new ArrayList<>();
/**
* A reference to the vehicle intended to process the transport order.
*/
private TCSObjectReference<Vehicle> intendedVehicle;
/**
* Properties of the transport order data.
*/
private final Map<String, String> properties = new TreeMap<>();
/**
* Creates a new instance of TransportOrderData, that performes
* XML telegram generation. This class implements also functions for
* management of data structures that contains the data of
* gui-generated elements and data need for creating a new XML telegram and
* for creating of a new transport order instances.
*/
public TransportOrderData() {
}
/**
* Adds a new DriveOrderStructure to this transport order.
*
* @param driveOrder The drive order that shall be added
*/
public void addDriveOrder(DriveOrderStructure driveOrder) {
Objects.requireNonNull(driveOrder, "driveOrder is null");
driveOrders.add(driveOrder);
}
/**
* Removes a <code>DriveOrderStructure</code> from the list of drive orders.
*
* @param index The index of the drive order in the list.
*/
public void removeDriveOrder(int index) {
driveOrders.remove(index);
}
/**
* Returns a list of matched destinations that have to be travelled when
* processing the new generated transport order.
*
* @return The list of destinations that have to be travelled when processing
* the new generated transport order.
*/
public List<DriveOrder.Destination> getDestinations() {
List<DriveOrder.Destination> destinations = new ArrayList<>(driveOrders.size());
for (DriveOrderStructure i : driveOrders) {
destinations.add(
new DriveOrder.Destination(i.getDriveOrderLocation())
.withOperation(i.getDriveOrderVehicleOperation())
);
}
return destinations;
}
/**
* Returns the properties of this transport order data.
*
* @return The properties
*/
public Map<String, String> getProperties() {
return properties;
}
/**
* Adds a property.
*
* @param key The key
* @param value The value
*/
public void addProperty(String key, String value) {
if (key == null || value == null) {
return;
}
properties.put(key, value);
}
/**
* Returns a list of drive orders.
*
* @return The list of drive orders.
*/
public List<DriveOrderStructure> getDriveOrders() {
return driveOrders;
}
/**
* Returns a deadline.
*
* @return The deadline.
*/
public Deadline getDeadline() {
return this.deadline;
}
/**
* Sets the currect deadline for representing transport order.
*
* @param newDeadline The new deadline.
*/
public void setDeadline(Deadline newDeadline) {
this.deadline = newDeadline;
}
/**
* Returns a reference to the vehicle intended to process the order.
*
* @return A reference to the vehicle intended to process the order.
*/
public TCSObjectReference<Vehicle> getIntendedVehicle() {
return intendedVehicle;
}
/**
* Sets a reference to the vehicle intended to process the order.
*
* @param vehicle A reference to the vehicle intended to process the order.
*/
public void setIntendedVehicle(TCSObjectReference<Vehicle> vehicle) {
intendedVehicle = vehicle;
}
/**
* The enumeration of possible default deadline values.
*/
public enum Deadline {
/**
* The deadline value is five minutes in the past.
*/
MINUS_FIVE_MINUTES("-5 min.", -60 * 5 * 1000),
/**
* The deadline value is five minutes in the future.
*/
PLUS_FIVE_MINUTES("5 min.", 60 * 5 * 1000),
/**
* The deadline value is a half hour in the past.
*/
MINUS_HALF_HOUR("-30 min.", -60 * 30 * 1000),
/**
* The deadline value is a half hour in the future.
*/
PLUS_HALF_HOUR("30 min.", 60 * 30 * 1000),
/**
* The deadline value is a one hour in the future.
*/
PLUS_ONE_HOUR(" 1 h.", 60 * 60 * 1000),
/**
* The deadline value is two hours in the future.
*/
PLUS_TWO_HOURS(" 2 h.", 2 * 60 * 60 * 1000);
/**
* The deadline value (in ms).
*/
private final int millis;
/**
* The deadline label.
*/
private final String label;
/**
* Creates a new Deadline.
*
* @param newLabel This deadline as a string
* @param deadline The value
*/
Deadline(String newLabel, int deadline) {
this.millis = deadline;
this.label = newLabel;
}
/**
* Returns a deadline value (in ms relative to the current time).
*
* @return The deadline value (in ms relative to the current time).
*/
public int getTime() {
return this.millis;
}
/**
* Returns an absolute time.
*
* @return The absolute time.
*/
public Date getAbsoluteTime() {
Calendar calendar = Calendar.getInstance();
calendar.add(Calendar.MILLISECOND, this.getTime());
return calendar.getTime();
}
@Override
public String toString() {
return this.label;
}
}
}

View File

@@ -0,0 +1,187 @@
// SPDX-FileCopyrightText: The openTCS Authors
// SPDX-License-Identifier: MIT
package org.opentcs.guing.plugins.panels.loadgenerator;
import static org.opentcs.guing.plugins.panels.loadgenerator.I18nPlantOverviewPanelLoadGenerator.BUNDLE_PATH;
import java.util.ArrayList;
import java.util.List;
import java.util.ResourceBundle;
import javax.swing.table.AbstractTableModel;
import org.opentcs.data.TCSObjectReference;
import org.opentcs.data.model.Vehicle;
import org.opentcs.guing.plugins.panels.loadgenerator.xmlbinding.TransportOrderEntry;
import org.opentcs.guing.plugins.panels.loadgenerator.xmlbinding.TransportOrdersDocument;
/**
* A table model for transport orders.
*/
class TransportOrderTableModel
extends
AbstractTableModel {
/**
* This classe's bundle.
*/
private static final ResourceBundle BUNDLE = ResourceBundle.getBundle(BUNDLE_PATH);
/**
* The column names.
*/
private static final String[] COLUMN_NAMES
= new String[]{
"#",
BUNDLE.getString(
"transportOrderTableModel.column_deadline.headerText"
),
BUNDLE.getString(
"transportOrderTableModel.column_vehicle.headerText"
)
};
/**
* The column classes.
*/
private static final Class<?>[] COLUMN_CLASSES
= new Class<?>[]{
Integer.class,
TransportOrderData.Deadline.class,
TCSObjectReference.class
};
/**
* The actual content.
*/
private final List<TransportOrderData> transportOrderDataList = new ArrayList<>();
/**
* Creates a new instance.
*/
TransportOrderTableModel() {
}
/**
* Adds a <code>TransportOrderData</code>.
*
* @param data The new transport order data
*/
public void addData(TransportOrderData data) {
int newIndex = transportOrderDataList.size();
transportOrderDataList.add(data);
fireTableRowsInserted(newIndex, newIndex);
}
/**
* Removes a <code>TransportOrderData</code>.
*
* @param row Index indicating which transport order data shall be removed
*/
public void removeData(int row) {
transportOrderDataList.remove(row);
fireTableRowsDeleted(row, row);
}
/**
* Returns the <code>TransportOrderData</code> at the given index.
*
* @param row Index indicating which data shall be returned
* @return The transport order data at the given index
*/
public TransportOrderData getDataAt(int row) {
if (row >= 0) {
return transportOrderDataList.get(row);
}
else {
return null;
}
}
@Override
public int getRowCount() {
return transportOrderDataList.size();
}
@Override
public int getColumnCount() {
return COLUMN_NAMES.length;
}
@Override
public Object getValueAt(int rowIndex, int columnIndex) {
TransportOrderData data = transportOrderDataList.get(rowIndex);
switch (columnIndex) {
case 0:
return rowIndex + 1;
case 1:
return data.getDeadline();
case 2:
return data.getIntendedVehicle();
default:
throw new IllegalArgumentException("Invalid columnIndex: " + columnIndex);
}
}
@Override
public String getColumnName(int columnIndex) {
return COLUMN_NAMES[columnIndex];
}
@Override
public Class<?> getColumnClass(int columnIndex) {
return COLUMN_CLASSES[columnIndex];
}
@Override
public boolean isCellEditable(int rowIndex, int columnIndex) {
switch (columnIndex) {
case 0:
return false;
case 1:
return true;
case 2:
return true;
default:
throw new IllegalArgumentException("Invalid columnIndex: " + columnIndex);
}
}
@SuppressWarnings("unchecked")
@Override
public void setValueAt(Object aValue, int rowIndex, int columnIndex) {
TransportOrderData data = transportOrderDataList.get(rowIndex);
switch (columnIndex) {
case 1:
data.setDeadline((TransportOrderData.Deadline) aValue);
break;
case 2:
data.setIntendedVehicle((TCSObjectReference<Vehicle>) aValue);
break;
default:
throw new IllegalArgumentException("Invalid columnIndex: " + columnIndex);
}
}
public TransportOrdersDocument toXmlDocument() {
TransportOrdersDocument result = new TransportOrdersDocument();
for (TransportOrderData curData : transportOrderDataList) {
result.getTransportOrders().add(
new TransportOrderEntry(
curData.getDeadline(),
curData.getDriveOrders(),
curData.getIntendedVehicle() == null ? null : curData.getIntendedVehicle().getName(),
curData.getProperties()
)
);
}
return result;
}
/**
* Returns the list containing all <code>TransportOrderData</code>.
*
* @return The list containing all data
*/
public List<TransportOrderData> getList() {
return transportOrderDataList;
}
}

View File

@@ -0,0 +1,109 @@
// SPDX-FileCopyrightText: The openTCS Authors
// SPDX-License-Identifier: MIT
package org.opentcs.guing.plugins.panels.loadgenerator.batchcreator;
import static java.util.Objects.requireNonNull;
import java.time.Instant;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import org.opentcs.access.KernelRuntimeException;
import org.opentcs.access.to.order.DestinationCreationTO;
import org.opentcs.access.to.order.TransportOrderCreationTO;
import org.opentcs.components.kernel.services.DispatcherService;
import org.opentcs.components.kernel.services.TransportOrderService;
import org.opentcs.data.order.TransportOrder;
import org.opentcs.guing.plugins.panels.loadgenerator.DriveOrderStructure;
import org.opentcs.guing.plugins.panels.loadgenerator.TransportOrderData;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* A batch generator for creating explicit transport orders.
*/
public class ExplicitOrderBatchGenerator
implements
OrderBatchCreator {
/**
* This class's Logger.
*/
private static final Logger LOG = LoggerFactory.getLogger(ExplicitOrderBatchGenerator.class);
/**
* The transport order service we talk to.
*/
private final TransportOrderService transportOrderService;
/**
* The dispatcher service.
*/
private final DispatcherService dispatcherService;
/**
* The TransportOrderData we're building the transport orders from.
*/
private final List<TransportOrderData> data;
/**
* Creates a new ExplicitOrderBatchGenerator.
*
* @param transportOrderService The portal.
* @param dispatcherService The dispatcher service.
* @param data The transport order data.
*/
public ExplicitOrderBatchGenerator(
TransportOrderService transportOrderService,
DispatcherService dispatcherService,
List<TransportOrderData> data
) {
this.transportOrderService = requireNonNull(transportOrderService, "transportOrderService");
this.dispatcherService = requireNonNull(dispatcherService, "dispatcherService");
this.data = requireNonNull(data, "data");
}
@Override
public Set<TransportOrder> createOrderBatch()
throws KernelRuntimeException {
Set<TransportOrder> createdOrders = new HashSet<>();
for (TransportOrderData curData : data) {
createdOrders.add(createSingleOrder(curData));
}
dispatcherService.dispatch();
return createdOrders;
}
private TransportOrder createSingleOrder(TransportOrderData curData)
throws KernelRuntimeException {
TransportOrder newOrder = transportOrderService.createTransportOrder(
new TransportOrderCreationTO(
"TOrder-",
createDestinations(curData.getDriveOrders())
)
.withIncompleteName(true)
.withDeadline(Instant.now().plusSeconds(curData.getDeadline().getTime() / 1000))
.withIntendedVehicleName(
curData.getIntendedVehicle() == null
? null
: curData.getIntendedVehicle().getName()
)
.withProperties(curData.getProperties())
);
return newOrder;
}
private List<DestinationCreationTO> createDestinations(List<DriveOrderStructure> structures) {
List<DestinationCreationTO> result = new ArrayList<>();
for (DriveOrderStructure currentOrder : structures) {
result.add(
new DestinationCreationTO(
currentOrder.getDriveOrderLocation().getName(),
currentOrder.getDriveOrderVehicleOperation()
)
);
}
return result;
}
}

View File

@@ -0,0 +1,23 @@
// SPDX-FileCopyrightText: The openTCS Authors
// SPDX-License-Identifier: MIT
package org.opentcs.guing.plugins.panels.loadgenerator.batchcreator;
import java.util.Set;
import org.opentcs.access.KernelRuntimeException;
import org.opentcs.data.order.TransportOrder;
/**
* Declares the methods of transport order batch creators.
*/
public interface OrderBatchCreator {
/**
* Creates a new transport order batch.
*
* @return The created transport orders
* @throws KernelRuntimeException In case the kernel threw an exception when
* creating the transport orders.
*/
Set<TransportOrder> createOrderBatch()
throws KernelRuntimeException;
}

View File

@@ -0,0 +1,130 @@
// SPDX-FileCopyrightText: The openTCS Authors
// SPDX-License-Identifier: MIT
package org.opentcs.guing.plugins.panels.loadgenerator.batchcreator;
import static java.util.Objects.requireNonNull;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Random;
import java.util.Set;
import java.util.stream.Collectors;
import org.opentcs.access.KernelRuntimeException;
import org.opentcs.access.to.order.DestinationCreationTO;
import org.opentcs.access.to.order.TransportOrderCreationTO;
import org.opentcs.components.kernel.services.DispatcherService;
import org.opentcs.components.kernel.services.TransportOrderService;
import org.opentcs.data.TCSObject;
import org.opentcs.data.TCSObjectReference;
import org.opentcs.data.model.Location;
import org.opentcs.data.model.LocationType;
import org.opentcs.data.order.DriveOrder.Destination;
import org.opentcs.data.order.TransportOrder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* Randomly creates batches of transport orders.
* Destinations and operations chosen are random and not guaranteed to work in
* a real plant.
*/
public class RandomOrderBatchCreator
implements
OrderBatchCreator {
/**
* This class's logger.
*/
private static final Logger LOG = LoggerFactory.getLogger(RandomOrderBatchCreator.class);
/**
* The transport order sergice we talk to.
*/
private final TransportOrderService transportOrderService;
/**
* The dispatcher service.
*/
private final DispatcherService dispatcherService;
/**
* The number of transport orders per batch.
*/
private final int batchSize;
/**
* The number of drive orders per transport order.
*/
private final int orderSize;
/**
* The locations in the model.
*/
private final List<Location> locations;
/**
* A random number generator for selecting locations and operations.
*/
private final Random random = new Random();
/**
* Creates a new RandomOrderBatchCreator.
*
* @param transportOrderService The transport order service.
* @param dispatcherService The dispatcher service.
* @param batchSize The number of transport orders per batch.
* @param orderSize The number of drive orders per transport order.
*/
public RandomOrderBatchCreator(
TransportOrderService transportOrderService,
DispatcherService dispatcherService,
int batchSize,
int orderSize
) {
this.transportOrderService = requireNonNull(transportOrderService, "transportOrderService");
this.dispatcherService = requireNonNull(dispatcherService, "dispatcherService");
this.batchSize = batchSize;
this.orderSize = orderSize;
this.locations = initializeLocations();
}
@Override
public Set<TransportOrder> createOrderBatch()
throws KernelRuntimeException {
Set<TransportOrder> createdOrders = new HashSet<>();
if (this.locations.isEmpty()) {
LOG.info("Could not find suitable destination locations");
return createdOrders;
}
for (int i = 0; i < batchSize; i++) {
createdOrders.add(createSingleOrder());
}
dispatcherService.dispatch();
return createdOrders;
}
private TransportOrder createSingleOrder()
throws KernelRuntimeException {
List<DestinationCreationTO> dests = new ArrayList<>();
for (int j = 0; j < orderSize; j++) {
Location destLoc = this.locations.get(random.nextInt(this.locations.size()));
dests.add(new DestinationCreationTO(destLoc.getName(), Destination.OP_NOP));
}
return transportOrderService.createTransportOrder(
new TransportOrderCreationTO("TOrder-", dests).withIncompleteName(true)
);
}
private List<Location> initializeLocations() {
Set<TCSObjectReference<LocationType>> suitableLocationTypeRefs
= transportOrderService.fetchObjects(LocationType.class)
.stream()
.filter(locationType -> locationType.isAllowedOperation(Destination.OP_NOP))
.map(TCSObject::getReference)
.collect(Collectors.toSet());
return transportOrderService.fetchObjects(Location.class)
.stream()
.filter(location -> !location.getAttachedLinks().isEmpty())
.filter(location -> suitableLocationTypeRefs.contains(location.getType()))
.collect(Collectors.toList());
}
}

View File

@@ -0,0 +1,6 @@
// SPDX-FileCopyrightText: The openTCS Authors
// SPDX-License-Identifier: MIT
/**
* A plugin panel providing a basic load generator.
*/
package org.opentcs.guing.plugins.panels.loadgenerator;

View File

@@ -0,0 +1,27 @@
// SPDX-FileCopyrightText: The openTCS Authors
// SPDX-License-Identifier: MIT
package org.opentcs.guing.plugins.panels.loadgenerator.trigger;
import org.opentcs.access.KernelRuntimeException;
/**
* Declares the methods of transport order generation triggers.
*/
public interface OrderGenerationTrigger {
/**
* Enables or disabled order generation.
*
* @param enabled true to enable, false to disable
*/
void setTriggeringEnabled(boolean enabled);
/**
* Triggers order generation.
*
* @throws KernelRuntimeException In case the kernel threw an exception when
* creating the transport orders.
*/
void triggerOrderGeneration()
throws KernelRuntimeException;
}

View File

@@ -0,0 +1,58 @@
// SPDX-FileCopyrightText: The openTCS Authors
// SPDX-License-Identifier: MIT
package org.opentcs.guing.plugins.panels.loadgenerator.trigger;
import java.util.Objects;
import org.opentcs.access.KernelRuntimeException;
import org.opentcs.guing.plugins.panels.loadgenerator.batchcreator.OrderBatchCreator;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* Triggers creation of transport orders only once.
*/
public class SingleOrderGenTrigger
implements
OrderGenerationTrigger {
/**
* This class's Logger.
*/
private static final Logger LOG = LoggerFactory.getLogger(SingleOrderGenTrigger.class);
/**
* The instance actually creating the new orders.
*/
private final OrderBatchCreator orderBatchCreator;
/**
* Creates a new SingleOrderGenTrigger.
*
* @param orderBatchCreator The order batch creator
*/
public SingleOrderGenTrigger(final OrderBatchCreator orderBatchCreator) {
this.orderBatchCreator = Objects.requireNonNull(
orderBatchCreator,
"orderBatchCreator is null"
);
}
@Override
public void setTriggeringEnabled(boolean enabled) {
if (enabled) {
triggerOrderGeneration();
}
}
@Override
public void triggerOrderGeneration()
throws KernelRuntimeException {
try {
if (orderBatchCreator != null) {
orderBatchCreator.createOrderBatch();
}
}
catch (KernelRuntimeException exc) {
LOG.warn("Exception triggering order generation, terminating triggering", exc);
}
}
}

View File

@@ -0,0 +1,149 @@
// SPDX-FileCopyrightText: The openTCS Authors
// SPDX-License-Identifier: MIT
package org.opentcs.guing.plugins.panels.loadgenerator.trigger;
import static java.util.Objects.requireNonNull;
import java.util.LinkedHashSet;
import java.util.Set;
import org.opentcs.access.KernelRuntimeException;
import org.opentcs.components.kernel.services.TCSObjectService;
import org.opentcs.customizations.ApplicationEventBus;
import org.opentcs.data.TCSObjectEvent;
import org.opentcs.data.order.TransportOrder;
import org.opentcs.guing.plugins.panels.loadgenerator.batchcreator.OrderBatchCreator;
import org.opentcs.util.event.EventHandler;
import org.opentcs.util.event.EventSource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* Triggers creation of a batch of orders if the number of transport orders
* in progress drop to or below a given threshold.
*/
public class ThresholdOrderGenTrigger
implements
EventHandler,
OrderGenerationTrigger {
/**
* This class's Logger.
*/
private static final Logger LOG = LoggerFactory.getLogger(ThresholdOrderGenTrigger.class);
/**
* Where we get events from.
*/
private final EventSource eventSource;
/**
* The object service we talk to.
*/
private final TCSObjectService objectService;
/**
* The orders that we know are in the system.
*/
private final Set<TransportOrder> knownOrders = new LinkedHashSet<>();
/**
* The threshold for order generation. If the number of orders "in progress"
* drops to or below this number, a batch of new orders is generated.
*/
private final int threshold;
/**
* The instance actually creating the new orders.
*/
private final OrderBatchCreator orderBatchCreator;
/**
* Creates a new instance.
*
* @param eventSource Where this instance registers for events.
* @param objectService The object service.
* @param threshold The threshold when new order are being created
* @param orderBatchCreator The order batch creator
*/
public ThresholdOrderGenTrigger(
final @ApplicationEventBus EventSource eventSource,
final TCSObjectService objectService,
final int threshold,
final OrderBatchCreator orderBatchCreator
) {
this.eventSource = requireNonNull(eventSource, "eventSource");
this.objectService = requireNonNull(objectService, "objectService");
this.threshold = threshold;
this.orderBatchCreator = requireNonNull(orderBatchCreator, "orderBatchCreator");
}
@Override
public void setTriggeringEnabled(boolean enabled) {
synchronized (knownOrders) {
if (enabled) {
// Remember all orders that are not finished, failed etc.
for (TransportOrder curOrder : objectService.fetchObjects(TransportOrder.class)) {
if (!curOrder.getState().isFinalState()) {
knownOrders.add(curOrder);
}
}
eventSource.subscribe(this);
if (knownOrders.size() <= threshold) {
triggerOrderGeneration();
}
}
else {
eventSource.unsubscribe(this);
knownOrders.clear();
}
}
}
@Override
public void triggerOrderGeneration()
throws KernelRuntimeException {
knownOrders.addAll(orderBatchCreator.createOrderBatch());
}
@Override
public void onEvent(Object event) {
if (!(event instanceof TCSObjectEvent)) {
return;
}
TCSObjectEvent objEvent = (TCSObjectEvent) event;
if (!(objEvent.getCurrentOrPreviousObjectState() instanceof TransportOrder)) {
return;
}
synchronized (knownOrders) {
TransportOrder eventOrder
= (TransportOrder) objEvent.getCurrentOrPreviousObjectState();
// If a new order was created, add it to the set of known orders.
if (TCSObjectEvent.Type.OBJECT_CREATED.equals(objEvent.getType())) {
knownOrders.add(eventOrder);
}
// If an order was removed, remove it here, too.
else if (TCSObjectEvent.Type.OBJECT_REMOVED.equals(objEvent.getType())) {
knownOrders.remove(eventOrder);
}
// If an order was modified, check if it's NOT "in progress". If it's not,
// i.e. if it's now finished, failed etc., remove it here, too.
else if (eventOrder.getState().isFinalState()) {
knownOrders.remove(eventOrder);
}
// Now let's check if the number of orders "in progress" has dropped below
// the threshold. If so, create a new batch of orders.
if (knownOrders.size() <= threshold) {
LOG.debug("orderCount = " + knownOrders.size() + ", triggering...");
trigger();
}
}
}
private void trigger() {
try {
triggerOrderGeneration();
}
catch (KernelRuntimeException exc) {
LOG.warn("Exception triggering order generation, terminating triggering", exc);
setTriggeringEnabled(false);
}
}
}

View File

@@ -0,0 +1,101 @@
// SPDX-FileCopyrightText: The openTCS Authors
// SPDX-License-Identifier: MIT
package org.opentcs.guing.plugins.panels.loadgenerator.trigger;
import java.util.Objects;
import org.opentcs.access.KernelRuntimeException;
import org.opentcs.guing.plugins.panels.loadgenerator.batchcreator.OrderBatchCreator;
import org.opentcs.util.CyclicTask;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* Triggers creation of a batch of orders after a given timeout.
*/
public class TimeoutOrderGenTrigger
implements
OrderGenerationTrigger {
/**
* This class's Logger.
*/
private static final Logger LOG = LoggerFactory.getLogger(TimeoutOrderGenTrigger.class);
/**
* The timeout after which to trigger (in ms).
*/
private final int timeout;
/**
* The instance actually creating the new orders.
*/
private final OrderBatchCreator orderBatchCreator;
/**
* The actual task triggering order generation.
*/
private volatile TriggerTask triggerTask;
/**
* Creates a new TimeoutOrderGenTrigger.
*
* @param timeout The timeout after which to trigger (in ms).
* @param orderBatchCreator The order batch creator
*/
public TimeoutOrderGenTrigger(
final int timeout,
final OrderBatchCreator orderBatchCreator
) {
this.timeout = timeout;
this.orderBatchCreator = Objects.requireNonNull(
orderBatchCreator,
"orderBatchCreator is null"
);
}
@Override
public void setTriggeringEnabled(boolean enabled) {
if (enabled) {
triggerTask = new TriggerTask(timeout);
Thread triggerThread = new Thread(triggerTask, "triggerTask");
triggerThread.start();
}
else {
if (triggerTask != null) {
triggerTask.terminate();
triggerTask = null;
}
}
}
@Override
public void triggerOrderGeneration()
throws KernelRuntimeException {
orderBatchCreator.createOrderBatch();
}
/**
* A task that repeatedly triggers order generation after a given timeout.
*/
private final class TriggerTask
extends
CyclicTask {
/**
* Creates a new instance.
*
* @param timeout The timeout after which to trigger order generation.
*/
private TriggerTask(int timeout) {
super(timeout);
}
@Override
protected void runActualTask() {
try {
triggerOrderGeneration();
}
catch (KernelRuntimeException exc) {
LOG.warn("Exception triggering order generation, terminating trigger task", exc);
this.terminate();
}
}
}
}

View File

@@ -0,0 +1,79 @@
// SPDX-FileCopyrightText: The openTCS Authors
// SPDX-License-Identifier: MIT
package org.opentcs.guing.plugins.panels.loadgenerator.xmlbinding;
import static java.util.Objects.requireNonNull;
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlType;
/**
* Stores a drive order definition for XML marshalling/unmarshalling.
*/
@XmlType(propOrder = {"locationName", "vehicleOperation"})
public class DriveOrderEntry {
/**
* The name of this drive order's location.
*/
private String locationName;
/**
* The operation to be executed at the location.
*/
private String vehicleOperation;
/**
* Creates a new instance.
*
* @param locationName The reference to the drive order's location.
* @param vehicleOperation The available operation type at the location.
*/
public DriveOrderEntry(String locationName, String vehicleOperation) {
this.locationName = requireNonNull(locationName, "locationName");
this.vehicleOperation = requireNonNull(vehicleOperation, "vehicleOperation");
}
/**
* Creates a new instance.
*/
public DriveOrderEntry() {
}
/**
* Returns a reference to the location.
*
* @return The reference to the location.
*/
@XmlAttribute(name = "locationName", required = true)
public String getLocationName() {
return locationName;
}
/**
* Sets the drive order location.
*
* @param locationName The new location.
*/
public void setLocationName(String locationName) {
this.locationName = locationName;
}
/**
* Returns this drive order's operation.
*
* @return The drive order's operation.
*/
@XmlAttribute(name = "vehicleOperation", required = true)
public String getVehicleOperation() {
return this.vehicleOperation;
}
/**
* Sets the drive order vehicle operation.
*
* @param vehicleOperation The new operation
*/
public void setVehicleOperation(String vehicleOperation) {
this.vehicleOperation = vehicleOperation;
}
}

View File

@@ -0,0 +1,236 @@
// SPDX-FileCopyrightText: The openTCS Authors
// SPDX-License-Identifier: MIT
package org.opentcs.guing.plugins.panels.loadgenerator.xmlbinding;
import static java.util.Objects.requireNonNull;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlType;
import org.opentcs.guing.plugins.panels.loadgenerator.DriveOrderStructure;
import org.opentcs.guing.plugins.panels.loadgenerator.TransportOrderData;
/**
* Stores a transport order definition for XML marshalling/unmarshalling.
*/
@XmlType(propOrder = {"properties", "driveOrders", "deadline", "intendedVehicle"})
public class TransportOrderEntry {
/**
* The transport order's deadline.
*/
private Deadline deadline = Deadline.PLUS_TWO_HOURS;
/**
* The drive orders the transport order consists of.
*/
private final List<DriveOrderEntry> driveOrders = new ArrayList<>();
/**
* The name of the vehicle intended to process the transport order.
*/
private String intendedVehicle;
/**
* Properties of the transport order data.
*/
private List<XMLMapEntry> properties = new ArrayList<>();
/**
* Creates a new instance.
*
* @param deadline The deadline of this transport order
* @param driveOrders A list containing the drive orders
* @param intendedVehicle The intended vehicle for this transport order
* @param properties A map containing the properties of this transport order
*/
public TransportOrderEntry(
TransportOrderData.Deadline deadline,
List<DriveOrderStructure> driveOrders,
String intendedVehicle,
Map<String, String> properties
) {
switch (deadline) {
case MINUS_FIVE_MINUTES:
this.deadline = Deadline.MINUS_FIVE_MINUTES;
break;
case PLUS_FIVE_MINUTES:
this.deadline = Deadline.PLUS_FIVE_MINUTES;
break;
case MINUS_HALF_HOUR:
this.deadline = Deadline.MINUS_HALF_HOUR;
break;
case PLUS_HALF_HOUR:
this.deadline = Deadline.PLUS_HALF_HOUR;
break;
case PLUS_ONE_HOUR:
this.deadline = Deadline.PLUS_ONE_HOUR;
break;
case PLUS_TWO_HOURS:
default:
this.deadline = Deadline.PLUS_TWO_HOURS;
break;
}
this.intendedVehicle = intendedVehicle;
for (Map.Entry<String, String> curEntry : properties.entrySet()) {
this.properties.add(
new XMLMapEntry(curEntry.getKey(), curEntry.getValue())
);
}
for (DriveOrderStructure curDOS : driveOrders) {
this.driveOrders.add(
new DriveOrderEntry(
curDOS.getDriveOrderLocation().getName(),
curDOS.getDriveOrderVehicleOperation()
)
);
}
}
/**
* Creates a new instance.
*/
public TransportOrderEntry() {
}
/**
* Returns the properties of this transport order.
*
* @return The properties
*/
@XmlElement(name = "property", required = true)
//@XmlJavaTypeAdapter(MapAdapter.class)
public List<XMLMapEntry> getProperties() {
return properties;
}
/**
* Returns the list of drive orders.
*
* @return The list of drive orders.
*/
@XmlElement(name = "driveOrder", required = true)
public List<DriveOrderEntry> getDriveOrders() {
return driveOrders;
}
/**
* Returns a deadline.
*
* @return The deadline.
*/
@XmlAttribute(name = "deadline", required = true)
public Deadline getDeadline() {
return this.deadline;
}
/**
* Sets the transport order's deadline.
*
* @param deadline The new deadline.
*/
public void setDeadline(Deadline deadline) {
this.deadline = requireNonNull(deadline, "deadline");
}
/**
* Returns a reference to the vehicle intended to process the order.
*
* @return A reference to the vehicle intended to process the order.
*/
@XmlAttribute(name = "intendedVehicle", required = true)
public String getIntendedVehicle() {
return intendedVehicle;
}
/**
* Sets a reference to the vehicle intended to process the order.
*
* @param vehicle A reference to the vehicle intended to process the order.
*/
public void setIntendedVehicle(String vehicle) {
intendedVehicle = vehicle;
}
/**
* The enumeration of possible default deadline values.
*/
public enum Deadline {
/**
* The deadline value is five minutes in the past.
*/
MINUS_FIVE_MINUTES,
/**
* The deadline value is five minutes in the future.
*/
PLUS_FIVE_MINUTES,
/**
* The deadline value is a half hour in the past.
*/
MINUS_HALF_HOUR,
/**
* The deadline value is a half hour in the future.
*/
PLUS_HALF_HOUR,
/**
* The deadline value is a one hour in the future.
*/
PLUS_ONE_HOUR,
/**
* The deadline value is two hours in the future.
*/
PLUS_TWO_HOURS;
}
/**
* A class to marshal the map of properties.
*/
@XmlType
public static class XMLMapEntry {
/**
* The key.
*/
private String key;
/**
* The value.
*/
private String value;
/**
* Creates an empty XMLMalEntry.
*/
public XMLMapEntry() {
}
/**
* Creates a new XMLMapEntry.
*
* @param key The key
* @param value The value
*/
public XMLMapEntry(String key, String value) {
this.key = key;
this.value = value;
}
@XmlAttribute
public String getKey() {
return key;
}
public void setKey(String key) {
this.key = key;
}
@XmlAttribute
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
}
}

View File

@@ -0,0 +1,141 @@
// SPDX-FileCopyrightText: The openTCS Authors
// SPDX-License-Identifier: MIT
package org.opentcs.guing.plugins.panels.loadgenerator.xmlbinding;
import static java.util.Objects.requireNonNull;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.StringReader;
import java.io.StringWriter;
import java.util.ArrayList;
import java.util.List;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlType;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
*/
@XmlRootElement(name = "transportOrders")
@XmlType(propOrder = {"transportOrders"})
public class TransportOrdersDocument {
/**
* This class's logger.
*/
private static final Logger LOG = LoggerFactory.getLogger(TransportOrdersDocument.class);
/**
* The transport orders.
*/
private final List<TransportOrderEntry> transportOrders = new ArrayList<>();
/**
* Creates a new instance.
*/
public TransportOrdersDocument() {
}
@XmlElement(name = "transportOrder")
public List<TransportOrderEntry> getTransportOrders() {
return transportOrders;
}
/**
* Marshals the data.
*
* @return Data as XML string
*/
public String toXml() {
StringWriter stringWriter = new StringWriter();
try {
JAXBContext jc = JAXBContext.newInstance(TransportOrdersDocument.class);
Marshaller marshaller = jc.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
marshaller.marshal(this, stringWriter);
}
catch (JAXBException exc) {
LOG.warn("Exception marshalling data", exc);
throw new IllegalStateException("Exception marshalling data", exc);
}
return stringWriter.toString();
}
/**
* Writes the file.
*
* @param file The file to write
* @throws IOException If an exception occured while writing
*/
public void toFile(File file)
throws IOException {
requireNonNull(file, "file");
try (OutputStream outStream = new FileOutputStream(file)) {
outStream.write(toXml().getBytes());
outStream.flush();
}
}
/**
* Reads a list of <code>TransportOrderXMLStructure</code>s from an XML file.
*
* @param xmlData The XML data
* @return The list of data
*/
public static TransportOrdersDocument fromXml(String xmlData) {
requireNonNull(xmlData, "xmlData");
StringReader stringReader = new StringReader(xmlData);
try {
JAXBContext jc = JAXBContext.newInstance(TransportOrdersDocument.class);
Unmarshaller unmarshaller = jc.createUnmarshaller();
Object o = unmarshaller.unmarshal(stringReader);
return (TransportOrdersDocument) o;
}
catch (JAXBException exc) {
LOG.warn("Exception unmarshalling data", exc);
throw new IllegalStateException("Exception unmarshalling data", exc);
}
}
/**
* Reads a list of <code>TransportOrderXMLStructure</code>s from a file.
*
* @param sourceFile The file
* @return The list of data
* @throws IOException If an exception occured while reading
*/
public static TransportOrdersDocument fromFile(File sourceFile)
throws IOException {
requireNonNull(sourceFile, "sourceFile");
final String path = sourceFile.getAbsolutePath();
if (!sourceFile.isFile() || !sourceFile.canRead()) {
throw new IOException(path + ": file not a regular file or unreadable");
}
int fileSize = (int) sourceFile.length();
byte[] buffer = new byte[fileSize];
try (InputStream inStream = new FileInputStream(sourceFile)) {
int bytesRead = inStream.read(buffer);
if (bytesRead != fileSize) {
throw new IOException(
"read() returned unexpected value: " + bytesRead + ", should be :" + fileSize
);
}
}
String fileContent = new String(buffer);
return fromXml(fileContent);
}
}

View File

@@ -0,0 +1,52 @@
# SPDX-FileCopyrightText: The openTCS Authors
# SPDX-License-Identifier: CC-BY-4.0
continuousLoadPanel.accessibleName=Continuous load
continuousLoadPanel.button_addDriveOrder.text=New drive order
continuousLoadPanel.button_addProperty.text=Add property
continuousLoadPanel.button_addTransportOrder.text=Add new order
continuousLoadPanel.button_addTransportOrder.tooltipText=Add empty transport order
continuousLoadPanel.button_deleteSelectedDriveOrder.text=Delete selected
continuousLoadPanel.button_deleteSelectedDriveOrder.tooltipText=Remove selected drive order
continuousLoadPanel.button_deleteSelectedOrder.text=Delete selected
continuousLoadPanel.button_deleteSelectedOrder.tooltipText=Remove selected transport order
continuousLoadPanel.button_open.text=Open
continuousLoadPanel.button_removeProperty.text=Remove property
continuousLoadPanel.button_save.text=Save
continuousLoadPanel.checkBox_enableOrderGeneration.text=Enable order generation
continuousLoadPanel.comboBox_locations.tooltipText=Available locations
continuousLoadPanel.comboBox_operationTypes.tooltipText=Allowed operations
continuousLoadPanel.label_unitDriveOrdersPerOrder.text=drive orders per transport order
continuousLoadPanel.label_unitOrdersAtATime.text=orders at a time,
continuousLoadPanel.label_unitOrdersToBeProcessed.text=orders to be processed
continuousLoadPanel.label_unitSeconds.text=seconds
continuousLoadPanel.optionPane_driveOrderEmpty.message=Every transport order must have at least one drive order.
continuousLoadPanel.optionPane_driveOrderEmpty.title=Drive orders missing
continuousLoadPanel.optionPane_driveOrderIncorrect.message=Every drive order must have a location and an operation.
continuousLoadPanel.optionPane_driveOrderIncorrect.title=Drive orders incorrect
continuousLoadPanel.optionPane_fileDoesNotExist.message=The chosen input file does not exist.
continuousLoadPanel.optionPane_fileDoesNotExist.title=File does not exist
continuousLoadPanel.optionPane_overwriteFileConfirmation.message=A file with the chosen name already exists, do you want to overwrite it?
continuousLoadPanel.optionPane_overwriteFileConfirmation.title=File exists
continuousLoadPanel.panel_driveOrders.border.title=Drive orders
continuousLoadPanel.panel_generateTrigger.border.title=Trigger for generating orders
continuousLoadPanel.panel_orderGeneration.border.title=Order generation
continuousLoadPanel.panel_orderProfile.border.title=Order profile
continuousLoadPanel.panel_properties.border.title=Properties
continuousLoadPanel.panel_transportOrderModelling.border.title=Transport order modelling
continuousLoadPanel.panel_transportOrders.border.title=Transport orders
continuousLoadPanel.radioButton_createOrdersAccordingDefinition.text=Create orders according to definition
continuousLoadPanel.radioButton_createOrdersRandomly.text=Create orders randomly:
continuousLoadPanel.radioButton_triggerAfterTimeout.text=After a timeout of
continuousLoadPanel.radioButton_triggerByOrderThreshold.text=If there are no more than
continuousLoadPanel.radioButton_triggerOnce.text=Create orders only once
continuousLoadPanel.tab_driveOrders.title=Drive orders
continuousLoadPanel.tab_properties.title=Properties
continuousLoadPanel.table_driveOrders.tooltipText=Drive orders in selected transport order
continuousLoadPanelFactory.panelDescription=Continuous load
driveOrderTableModel.column_location.headerText=Location
driveOrderTableModel.column_operation.headerText=Operation
propertyTableModel.column_key.headerText=Key
propertyTableModel.column_value.headerText=Value
transportOrderTableModel.column_deadline.headerText=Deadline
transportOrderTableModel.column_vehicle.headerText=Vehicle

View File

@@ -0,0 +1,49 @@
# SPDX-FileCopyrightText: The openTCS Authors
# SPDX-License-Identifier: CC-BY-4.0
continuousLoadPanel.accessibleName=Kontinuierliche Last
continuousLoadPanel.button_addDriveOrder.text=Neuer Fahrauftrag
continuousLoadPanel.button_addProperty.text=Hinzuf\u00fcgen
continuousLoadPanel.button_addTransportOrder.text=Transportauftrag hinzuf\u00fcgen
continuousLoadPanel.button_addTransportOrder.tooltipText=Leeren Transportauftrag hinzuf\u00fcgen
continuousLoadPanel.button_deleteSelectedDriveOrder.tooltipText=Ausgew\u00e4hlten Fahrauftrag l\u00f6schen
continuousLoadPanel.button_deleteSelectedOrder.text=Auswahl l\u00f6schen
continuousLoadPanel.button_deleteSelectedOrder.tooltipText=Ausgew\u00e4hlten Transportauftrag l\u00f6schen
continuousLoadPanel.button_open.text=\u00d6ffnen
continuousLoadPanel.button_removeProperty.text=Entfernen
continuousLoadPanel.button_save.text=Speichern
continuousLoadPanel.checkBox_enableOrderGeneration.text=Auftragsgenerator einschalten
continuousLoadPanel.comboBox_locations.tooltipText=Verf\u00fcgbare Orte
continuousLoadPanel.comboBox_operationTypes.tooltipText=Erlaubte Operationen
continuousLoadPanel.label_unitDriveOrdersPerOrder.text=Fahrauftr\u00e4ge pro Transportauftrag
continuousLoadPanel.label_unitOrdersAtATime.text=Auftr\u00e4ge auf einmal,
continuousLoadPanel.label_unitOrdersToBeProcessed.text=zu bearbeitende Auftr\u00e4ge
continuousLoadPanel.label_unitSeconds.text=Sekunden
continuousLoadPanel.optionPane_driveOrderEmpty.message=Jeder Transportauftrag muss wenigstens einen Fahrauftrag besitzen.
continuousLoadPanel.optionPane_driveOrderEmpty.title=Fahrauftr\u00e4ge fehlen
continuousLoadPanel.optionPane_driveOrderIncorrect.message=Jeder Fahrauftrag muss eine Station und eine Operation besitzen\n.
continuousLoadPanel.optionPane_driveOrderIncorrect.title=Fahrauftr\u00e4ge fehlerhaft
continuousLoadPanel.optionPane_fileDoesNotExist.message=Die ausgew\u00e4hlte Datei existiert nicht.
continuousLoadPanel.optionPane_fileDoesNotExist.title=Datei existiert nicht
continuousLoadPanel.optionPane_overwriteFileConfirmation.message=Eine Datei mit dem gew\u00e4hlten Namen existiert bereits, wollen Sie sie \u00fcberschreiben?
continuousLoadPanel.optionPane_overwriteFileConfirmation.title=Datei existiert
continuousLoadPanel.panel_driveOrders.border.title=Fahrauftr\u00e4ge
continuousLoadPanel.panel_generateTrigger.border.title=Ausl\u00f6ser f\u00fcr Auftragsgenerierung
continuousLoadPanel.panel_orderGeneration.border.title=Auftragsgenerierung
continuousLoadPanel.panel_orderProfile.border.title=Auftragsprofil
continuousLoadPanel.panel_transportOrderModelling.border.title=Transportauftragsmodellierung
continuousLoadPanel.panel_transportOrders.border.title=Transportauftr\u00e4ge
continuousLoadPanel.radioButton_createOrdersAccordingDefinition.text=Auftr\u00e4ge nach Vorgabe erzeugen
continuousLoadPanel.radioButton_createOrdersRandomly.text=Auftr\u00e4ge zuf\u00e4llig erzeugen:
continuousLoadPanel.radioButton_triggerAfterTimeout.text=Nach einer Wartezeit von
continuousLoadPanel.radioButton_triggerByOrderThreshold.text=Falls nicht mehr als
continuousLoadPanel.radioButton_triggerOnce.text=Auftr\u00e4ge nur einmal erzeugen
continuousLoadPanel.tab_driveOrders.title=Fahrauftr\u00e4ge
continuousLoadPanel.tab_properties.title=Eigenschaften
continuousLoadPanel.table_driveOrders.tooltipText=Fahrauftr\u00e4ge im ausgew\u00e4hlten Transportauftrag
driveOrderTableModel.column_location.headerText=Station
driveOrderTableModel.column_operation.headerText=Operation
propertyTableModel.column_key.headerText=Schl\u00fcssel
propertyTableModel.column_value.headerText=Wert
transportOrderTableModel.column_deadline.headerText=Frist
transportOrderTableModel.column_vehicle.headerText=Fahrzeug

View File

@@ -0,0 +1,146 @@
// SPDX-FileCopyrightText: The openTCS Authors
// SPDX-License-Identifier: MIT
package org.opentcs.guing.plugins.panels.loadgenerator.batchcreator;
import static java.util.UUID.randomUUID;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.empty;
import static org.hamcrest.Matchers.hasSize;
import static org.hamcrest.Matchers.is;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import java.util.List;
import java.util.Set;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.opentcs.access.to.order.TransportOrderCreationTO;
import org.opentcs.components.kernel.services.DispatcherService;
import org.opentcs.components.kernel.services.TransportOrderService;
import org.opentcs.data.model.Location;
import org.opentcs.data.model.LocationType;
import org.opentcs.data.model.Point;
import org.opentcs.data.order.TransportOrder;
/**
* Tests for {@link RandomOrderBatchCreator}.
*/
class RandomOrderBatchCreatorTest {
private final Point point = new Point("point1");
private final LocationType unsuitableLocType = new LocationType("unsuitableLocType")
.withAllowedOperations(List.of("park"));
private final LocationType suitableLocType = new LocationType("suitableLocType")
.withAllowedOperations(List.of("park", "NOP"));
private final Location unsuitableLoc = new Location(
"unsuitableLoc",
unsuitableLocType.getReference()
);
private final Location suitableLoc = new Location(
"suitableLoc",
suitableLocType.getReference()
);
private DispatcherService dispatcherService;
private TransportOrderService transportOrderService;
@BeforeEach
void setUp() {
dispatcherService = mock(DispatcherService.class);
transportOrderService = mock(TransportOrderService.class);
}
@Test
void givenUnsuitableTypeWithoutLinkThenCreateNoOrders() {
when(transportOrderService.fetchObjects(LocationType.class))
.thenReturn(Set.of(unsuitableLocType));
when(transportOrderService.fetchObjects(Location.class))
.thenReturn(Set.of(unsuitableLoc));
RandomOrderBatchCreator batchCreator = new RandomOrderBatchCreator(transportOrderService,
dispatcherService,
10,
3);
Set<TransportOrder> result = batchCreator.createOrderBatch();
assertThat(result, is(empty()));
verify(transportOrderService, never())
.createTransportOrder(any(TransportOrderCreationTO.class));
}
@Test
void givenSuitableTypeWithoutLinkThenCreateNoOrders() {
when(transportOrderService.fetchObjects(LocationType.class))
.thenReturn(Set.of(suitableLocType));
when(transportOrderService.fetchObjects(Location.class))
.thenReturn(Set.of(suitableLoc));
RandomOrderBatchCreator batchCreator = new RandomOrderBatchCreator(transportOrderService,
dispatcherService,
10,
3);
Set<TransportOrder> result = batchCreator.createOrderBatch();
assertThat(result, is(empty()));
verify(transportOrderService, never())
.createTransportOrder(any(TransportOrderCreationTO.class));
}
@Test
void givenUnsuitableTypeWithLinkThenCreateNoOrders() {
Location.Link unsuitableLink = new Location.Link(
unsuitableLoc.getReference(),
point.getReference()
);
when(transportOrderService.fetchObjects(LocationType.class))
.thenReturn(Set.of(unsuitableLocType));
when(transportOrderService.fetchObjects(Location.class))
.thenReturn(Set.of(unsuitableLoc.withAttachedLinks(Set.of(unsuitableLink))));
RandomOrderBatchCreator batchCreator = new RandomOrderBatchCreator(
transportOrderService,
dispatcherService,
10,
3
);
Set<TransportOrder> result = batchCreator.createOrderBatch();
assertThat(result, is(empty()));
verify(transportOrderService, never())
.createTransportOrder(any(TransportOrderCreationTO.class));
}
@Test
void givenSuitableTypeWithLinkThenCreateOrders() {
Location.Link suitableLink = new Location.Link(
suitableLoc.getReference(),
point.getReference()
);
when(transportOrderService.fetchObjects(LocationType.class))
.thenReturn(Set.of(suitableLocType));
when(transportOrderService.fetchObjects(Location.class))
.thenReturn(Set.of(suitableLoc.withAttachedLinks(Set.of(suitableLink))));
when(transportOrderService.createTransportOrder(any(TransportOrderCreationTO.class)))
.thenAnswer(
invocation -> new TransportOrder(
randomUUID().toString(),
List.of()
)
);
RandomOrderBatchCreator batchCreator = new RandomOrderBatchCreator(
transportOrderService,
dispatcherService,
10,
3
);
Set<TransportOrder> result = batchCreator.createOrderBatch();
assertThat(result, hasSize(10));
verify(transportOrderService, times(10))
.createTransportOrder(any(TransportOrderCreationTO.class));
}
}