Started transportation job queue
This commit is contained in:
@@ -36,6 +36,9 @@
|
|||||||
<Compile Include="POUs\Scheduler\DUTs\ST_Transition.TcDUT">
|
<Compile Include="POUs\Scheduler\DUTs\ST_Transition.TcDUT">
|
||||||
<SubType>Code</SubType>
|
<SubType>Code</SubType>
|
||||||
</Compile>
|
</Compile>
|
||||||
|
<Compile Include="POUs\Scheduler\DUTs\ST_TransJob.TcDUT">
|
||||||
|
<SubType>Code</SubType>
|
||||||
|
</Compile>
|
||||||
<Compile Include="POUs\Scheduler\GVLs\GVL_Scheduler.TcGVL">
|
<Compile Include="POUs\Scheduler\GVLs\GVL_Scheduler.TcGVL">
|
||||||
<SubType>Code</SubType>
|
<SubType>Code</SubType>
|
||||||
<LinkAlways>true</LinkAlways>
|
<LinkAlways>true</LinkAlways>
|
||||||
@@ -49,6 +52,9 @@
|
|||||||
<Compile Include="POUs\Scheduler\ITFs\I_Transport.TcIO">
|
<Compile Include="POUs\Scheduler\ITFs\I_Transport.TcIO">
|
||||||
<SubType>Code</SubType>
|
<SubType>Code</SubType>
|
||||||
</Compile>
|
</Compile>
|
||||||
|
<Compile Include="POUs\Scheduler\POUs\FB_JobQueue.TcPOU">
|
||||||
|
<SubType>Code</SubType>
|
||||||
|
</Compile>
|
||||||
<Compile Include="POUs\Scheduler\POUs\FB_Product.TcPOU">
|
<Compile Include="POUs\Scheduler\POUs\FB_Product.TcPOU">
|
||||||
<SubType>Code</SubType>
|
<SubType>Code</SubType>
|
||||||
</Compile>
|
</Compile>
|
||||||
@@ -112,8 +118,8 @@
|
|||||||
<ProjectExtensions>
|
<ProjectExtensions>
|
||||||
<PlcProjectOptions>
|
<PlcProjectOptions>
|
||||||
<XmlArchive>
|
<XmlArchive>
|
||||||
<Data>
|
<Data>
|
||||||
<o xml:space="preserve" t="OptionKey">
|
<o xml:space="preserve" t="OptionKey">
|
||||||
<v n="Name">"<ProjectRoot>"</v>
|
<v n="Name">"<ProjectRoot>"</v>
|
||||||
<d n="SubKeys" t="Hashtable" ckt="String" cvt="OptionKey">
|
<d n="SubKeys" t="Hashtable" ckt="String" cvt="OptionKey">
|
||||||
<v>{192FAD59-8248-4824-A8DE-9177C94C195A}</v>
|
<v>{192FAD59-8248-4824-A8DE-9177C94C195A}</v>
|
||||||
@@ -189,14 +195,14 @@
|
|||||||
</d>
|
</d>
|
||||||
<d n="Values" t="Hashtable" />
|
<d n="Values" t="Hashtable" />
|
||||||
</o>
|
</o>
|
||||||
</Data>
|
</Data>
|
||||||
<TypeList>
|
<TypeList>
|
||||||
<Type n="Boolean">System.Boolean</Type>
|
<Type n="Boolean">System.Boolean</Type>
|
||||||
<Type n="Hashtable">System.Collections.Hashtable</Type>
|
<Type n="Hashtable">System.Collections.Hashtable</Type>
|
||||||
<Type n="OptionKey">{54dd0eac-a6d8-46f2-8c27-2f43c7e49861}</Type>
|
<Type n="OptionKey">{54dd0eac-a6d8-46f2-8c27-2f43c7e49861}</Type>
|
||||||
<Type n="String">System.String</Type>
|
<Type n="String">System.String</Type>
|
||||||
</TypeList>
|
</TypeList>
|
||||||
</XmlArchive>
|
</XmlArchive>
|
||||||
</PlcProjectOptions>
|
</PlcProjectOptions>
|
||||||
</ProjectExtensions>
|
</ProjectExtensions>
|
||||||
</Project>
|
</Project>
|
||||||
26
PLC/POUs/Scheduler/DUTs/ST_TransJob.TcDUT
Normal file
26
PLC/POUs/Scheduler/DUTs/ST_TransJob.TcDUT
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<TcPlcObject Version="1.1.0.1">
|
||||||
|
<DUT Name="ST_TransJob" Id="{e6905112-b0c5-4499-9e9b-aaa153fe4e4d}">
|
||||||
|
<Declaration><![CDATA[TYPE ST_TransJob :
|
||||||
|
STRUCT
|
||||||
|
// Station to pick from
|
||||||
|
uiFromNodeID : UINT;
|
||||||
|
// Station to put into
|
||||||
|
uiToNodeID : UINT;
|
||||||
|
// Static priority from recipe
|
||||||
|
iStatPrio : INT;
|
||||||
|
// Dynamic priority from process
|
||||||
|
iDynPrio : INT;
|
||||||
|
// Prio sum
|
||||||
|
iSumPrio : INT;
|
||||||
|
// Time this job was created
|
||||||
|
// The older the job the higher the priority
|
||||||
|
uliTimeCreated : ULINT;
|
||||||
|
|
||||||
|
// Is this job in the queue still valid
|
||||||
|
xValid : BOOL := TRUE;
|
||||||
|
END_STRUCT
|
||||||
|
END_TYPE
|
||||||
|
]]></Declaration>
|
||||||
|
</DUT>
|
||||||
|
</TcPlcObject>
|
||||||
@@ -9,6 +9,12 @@ VAR_GLOBAL CONSTANT
|
|||||||
|
|
||||||
// Scheduler constants
|
// Scheduler constants
|
||||||
MAX_STATIONS : UINT := 10;
|
MAX_STATIONS : UINT := 10;
|
||||||
|
|
||||||
|
// Factor to calc dynmaic priority from age of job in prio/s
|
||||||
|
AGE_FACTOR : REAL := 1.0;
|
||||||
|
|
||||||
|
// Job queue constants
|
||||||
|
MAX_JOBS_IN_QUEUE : UINT := 10;
|
||||||
END_VAR]]></Declaration>
|
END_VAR]]></Declaration>
|
||||||
</GVL>
|
</GVL>
|
||||||
</TcPlcObject>
|
</TcPlcObject>
|
||||||
103
PLC/POUs/Scheduler/POUs/FB_JobQueue.TcPOU
Normal file
103
PLC/POUs/Scheduler/POUs/FB_JobQueue.TcPOU
Normal file
@@ -0,0 +1,103 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<TcPlcObject Version="1.1.0.1">
|
||||||
|
<POU Name="FB_JobQueue" Id="{b05c10aa-a132-426c-9adb-9c3d92e348cd}" SpecialFunc="None">
|
||||||
|
<Declaration><![CDATA[FUNCTION_BLOCK FB_JobQueue
|
||||||
|
VAR_INPUT
|
||||||
|
END_VAR
|
||||||
|
VAR_OUTPUT
|
||||||
|
END_VAR
|
||||||
|
VAR
|
||||||
|
_astJobQueue : ARRAY[0..(GVL_Scheduler.MAX_JOBS_IN_QUEUE - 1)] OF ST_TransJob;
|
||||||
|
_uiJobCount : UINT := 0;
|
||||||
|
END_VAR
|
||||||
|
]]></Declaration>
|
||||||
|
<Implementation>
|
||||||
|
<ST><![CDATA[]]></ST>
|
||||||
|
</Implementation>
|
||||||
|
<Method Name="FB_Init" Id="{59b2fc0f-4c7e-4fd5-97a2-d54f83d37be4}">
|
||||||
|
<Declaration><![CDATA[//FB_Init is always available implicitly and it is used primarily for initialization.
|
||||||
|
//The return value is not evaluated. For a specific influence, you can also declare the
|
||||||
|
//methods explicitly and provide additional code there with the standard initialization
|
||||||
|
//code. You can evaluate the return value.
|
||||||
|
METHOD FB_Init: BOOL
|
||||||
|
VAR_INPUT
|
||||||
|
bInitRetains: BOOL; // TRUE: the retain variables are initialized (reset warm / reset cold)
|
||||||
|
bInCopyCode: BOOL; // TRUE: the instance will be copied to the copy code afterward (online change)
|
||||||
|
END_VAR
|
||||||
|
VAR
|
||||||
|
_uiCnt : UINT;
|
||||||
|
END_VAR]]></Declaration>
|
||||||
|
<Implementation>
|
||||||
|
<ST><![CDATA[// Set all jobs to false
|
||||||
|
FOR _uiCnt := 0 TO (GVL_Scheduler.MAX_JOBS_IN_QUEUE - 1) DO
|
||||||
|
_astJobQueue[_uiCnt].xValid := FALSE;
|
||||||
|
END_FOR
|
||||||
|
|
||||||
|
// No jobs in queue
|
||||||
|
_uiJobCount := 0;]]></ST>
|
||||||
|
</Implementation>
|
||||||
|
</Method>
|
||||||
|
<Method Name="M_AddJob" Id="{c7959fb9-7c57-4429-b989-c0befdd4ac38}">
|
||||||
|
<Declaration><![CDATA[METHOD M_AddJob : BOOL
|
||||||
|
VAR_INPUT
|
||||||
|
stJob : ST_TransJob;
|
||||||
|
END_VAR
|
||||||
|
]]></Declaration>
|
||||||
|
<Implementation>
|
||||||
|
<ST><![CDATA[// Check if queue is full
|
||||||
|
IF _uiJobCount >= GVL_Scheduler.MAX_JOBS_IN_QUEUE THEN
|
||||||
|
M_AddJob := FALSE;
|
||||||
|
RETURN;
|
||||||
|
END_IF
|
||||||
|
|
||||||
|
_uiJobCount := _uiJobCount + 1;
|
||||||
|
_astJobQueue[_uiJobCount] := stJob;
|
||||||
|
_astJobQueue[_uiJobCount].xValid := TRUE;
|
||||||
|
_astJobQueue[_uiJobCount].uliTimeCreated := F_GetSystemTime();
|
||||||
|
M_AddJob := TRUE;]]></ST>
|
||||||
|
</Implementation>
|
||||||
|
</Method>
|
||||||
|
<Method Name="M_GetHighest" Id="{26fa0379-d921-41a3-a15c-b3ff597c1d37}">
|
||||||
|
<Declaration><![CDATA[METHOD M_GetHighest : BOOL
|
||||||
|
VAR_OUTPUT
|
||||||
|
stJob : ST_TransJob;
|
||||||
|
END_VAR
|
||||||
|
VAR
|
||||||
|
_iMaxPrio : INT := -32768;
|
||||||
|
_uiIndex : UINT;
|
||||||
|
_ulTimestamp : ULINT;
|
||||||
|
_rDynPrio : REAL;
|
||||||
|
|
||||||
|
_uiCnt : UINT;
|
||||||
|
END_VAR]]></Declaration>
|
||||||
|
<Implementation>
|
||||||
|
<ST><![CDATA[// No jobs to return
|
||||||
|
IF _uiJobCount = 0 THEN
|
||||||
|
M_GetHighest := FALSE;
|
||||||
|
RETURN;
|
||||||
|
END_IF
|
||||||
|
|
||||||
|
_ulTimestamp := F_GetSystemTime();
|
||||||
|
|
||||||
|
// Find job with highest priority also update dyn prio
|
||||||
|
FOR _uiCnt := 0 TO _uiJobCount DO
|
||||||
|
// Only recalc and check if job is valid
|
||||||
|
IF _astJobQueue[_uiCnt].xValid THEN
|
||||||
|
// Recalculate dynamic priority (100ns intervalls to seconds)
|
||||||
|
_rDynPrio := ULINT_TO_REAL(_ulTimestamp - _astJobQueue[_uiCnt].uliTimeCreated) *1E-7 * GVL_Scheduler.AGE_FACTOR;
|
||||||
|
IF _rDynPrio > 32767.0 THEN
|
||||||
|
_rDynPrio := 32767.0;
|
||||||
|
END_IF
|
||||||
|
_astJobQueue[_uiCnt].iDynPrio := REAL_TO_INT(_rDynPrio);
|
||||||
|
|
||||||
|
// Check for highest priority
|
||||||
|
IF (_astJobQueue[_uiCnt].iStatPrio + _astJobQueue[_uiCnt].iDynPrio) > _iMaxPrio THEN
|
||||||
|
_iMaxPrio :=
|
||||||
|
END_IF
|
||||||
|
END_IF
|
||||||
|
|
||||||
|
END_FOR]]></ST>
|
||||||
|
</Implementation>
|
||||||
|
</Method>
|
||||||
|
</POU>
|
||||||
|
</TcPlcObject>
|
||||||
@@ -10,7 +10,7 @@ VAR
|
|||||||
_aiStations : ARRAY[1..(GVL_Scheduler.MAX_STATIONS)] OF I_Station;
|
_aiStations : ARRAY[1..(GVL_Scheduler.MAX_STATIONS)] OF I_Station;
|
||||||
_uiStationCount : UINT := 0;
|
_uiStationCount : UINT := 0;
|
||||||
|
|
||||||
_fbTransport : ARRAY[1..(GVL_Scheduler.MAX_STATIONS)] OF I_Station;
|
_fbTransport : I_Station;
|
||||||
_uiTransportCnt : UINT := 0;
|
_uiTransportCnt : UINT := 0;
|
||||||
|
|
||||||
_uiCnt : UINT;
|
_uiCnt : UINT;
|
||||||
@@ -19,7 +19,10 @@ VAR
|
|||||||
_fbProduct : I_Product;
|
_fbProduct : I_Product;
|
||||||
END_VAR]]></Declaration>
|
END_VAR]]></Declaration>
|
||||||
<Implementation>
|
<Implementation>
|
||||||
<ST><![CDATA[FOR _
|
<ST><![CDATA[IF (NOT _fbTransport.P_Available) THEN
|
||||||
|
// No need to check the station if we don't have a transport ready
|
||||||
|
RETURN;
|
||||||
|
END_IF
|
||||||
|
|
||||||
|
|
||||||
FOR _uiCnt := 1 TO _uiStationCount DO
|
FOR _uiCnt := 1 TO _uiStationCount DO
|
||||||
@@ -29,7 +32,9 @@ FOR _uiCnt := 1 TO _uiStationCount DO
|
|||||||
|
|
||||||
// Check if there is a station available
|
// Check if there is a station available
|
||||||
IF _uiNextAvailStation <> 0 THEN
|
IF _uiNextAvailStation <> 0 THEN
|
||||||
|
// Skip reservation for now
|
||||||
// _aiStations[_uiNextAvailStation].M_Reserve();
|
// _aiStations[_uiNextAvailStation].M_Reserve();
|
||||||
|
// Create transport job
|
||||||
END_IF
|
END_IF
|
||||||
END_IF
|
END_IF
|
||||||
END_FOR]]></ST>
|
END_FOR]]></ST>
|
||||||
|
|||||||
Reference in New Issue
Block a user