iml130 / pfdl Goto Github PK
View Code? Open in Web Editor NEWA Production Flow Description Language for an Order-Centric Production
Home Page: https://iml130.github.io/pfdl/
License: MIT License
A Production Flow Description Language for an Order-Centric Production
Home Page: https://iml130.github.io/pfdl/
License: MIT License
The grammar can be cleaned up to make it more clearer / more understandable.
Some examples:
Changes like these, would make the grammar and the parser code smaller -> More clearer
See the #37. Here tests got triggered on push as well on the PR:
and
Running tests once should be sufficient.
The callback functions for task or service calls return information about the called entity. However, if there are calls inside a counting or parallel loop, the callbacks do not provide information about the ith iteration. Consider the following example:
Loop i To cr.parts_count
millingTask
In
cr.sheet_parts[i]
If the task_started
callback is triggered multiple times (for multiple iterations) it is necessary to provde the exact value of the counting variable i
. Currently, all callbacks only provide the information that there is a variable i and not the value itself.
To allow users to write their own plugins for the PFDL without modifying the core code, we need to implement a plugin system that allows the usage and the import of an arbitrary amount of plugins. In Addition, the existing PFDL code most likely needs to be modified (more modularisation, clearer interfaces, ...) to allow for better plugin developement.
In parallel Loop Conditions it is possible to hand over a specific position of an array variable to a task/service. E.g.
Parallel Loop i To cr.parts_count
paintingAndCuttingTask
In
cr.sheet_parts[i]
However, it is not possible to specify such a field position as output. As a consequence, it is not possible to specify an output for parallel loops since there will be a loss of data if the whole array is defined as input and output, e.g.
cr{
sheet_parts = [0,0,0],
parts_count = 3
}
Parallel Loop i cr.parts_count
paintingAndCuttingTask
In
cr.sheet_parts
Out
cr.sheet_parts
Here, each of the parallel tasks get the initial input value sheet_parts = [0,0,0]. Since the output of each task writes the variable cr.sheet_parts, the results of the first two paintingAndCuttingTasks that are finished are lost and only the one that finished last is saved.
There are still Unit Tests missing for a few classes and files. To get closer to 100% Code Coverage, Unit Tests for the following classes and files needs to be added:
It is not possible to define services inside a parallel condition, but only tasks. However it is possible to use services inside counting loops, while loops and parallel loops. It would be great to enable the use of services inside parallel conditions. otherwise the petri net gets unnecessary places and transitions and becomes more complex.
Currently the petri net as a formal representation of the PFDL is hard coded in the scheduler. To increase the modularity it could be reasonable to create an interface in the scheduler where arbitrary models (e.g statemachines) can be registered to schedule instead of the petri net. However, the registered callback functions in the scheduler should still work the same way.
To unify the style of our commits, we could use Conventional Commits. It provides a set of rules on how to write a commit message.
An example commit message looks like the following:
<type>[optional scope]: <description>
[optional body]
[optional footer(s)]
Here, type is an identifier like "fix" or "feat".
Currently not all semantic error messages are printed correctly or at all. Due to the fact that the semantic check is executed after the parsing, a way of saving the context infos had to be implemented. Currently, not all informations about the specific parts of the program are saved. Find a way to preserve the context information for every bit of PFDL code in the SemanticErrorChecker
to provide proper error messages.
An example for this issue is shown below:
The attribute not an attribute
is not defined in the Struct Color
. The error highlight should appear in the same row as the attribute and not at the Struct name. Currently, the SemanticErrorChecker
do not have enough information to display it at the correct position.
If a struct is instantiated, for example in a Service call, the struct can contain an array. This array has no information about the type of its elements. For simple datatypes like number or string, it can be set through the values of the array. If the values of the array are also structs, which has to be instantiated too, it is not known to which struct defintion they belong.
It could be set in the semantic validation when the Struct instances are checked.
In the PFDL, only lowercase letters (e.g. fields in structures) or only uppercase letters (e.g. service names) are allowed as the first letter for some components. For users it is sometimes very difficult to understand the error, because the error message, depending on the content of the task can be quite large. The following error message is a result of writing ProductionTask instead of productionTask
mismatched input 'ProductionTask' expecting STARTS_WITH_LOWER_C_STR
File ./PFDL_Examples/test.pfdl, in line 16:5
extraneous input '{' expecting {<EOF>, 'Struct', 'Task', NL}
File ./PFDL_Examples/test.pfdl, in line 20:12
extraneous input 'dedent' expecting {<EOF>, 'Struct', 'Task', NL}
File ./PFDL_Examples/test.pfdl, in line 29:13
extraneous input 'dedent' expecting {<EOF>, 'Struct', 'Task', NL}
File ./PFDL_Examples/test.pfdl, in line 31:34
extraneous input 'Model_generation' expecting {<EOF>, 'Struct', 'Task', NL}
File ./PFDL_Examples/test.pfdl, in line 33:4
extraneous input 'Transport' expecting {<EOF>, 'Struct', 'Task', NL}
File ./PFDL_Examples/test.pfdl, in line 34:4
extraneous input 'dedent' expecting {<EOF>, 'Struct', 'Task', NL}
File ./PFDL_Examples/test.pfdl, in line 36:14
extraneous input 'dedent' expecting {<EOF>, 'Struct', 'Task', NL}
File ./PFDL_Examples/test.pfdl, in line 38:34
extraneous input 'Disassemble_gear' expecting {<EOF>, 'Struct', 'Task', NL}
File ./PFDL_Examples/test.pfdl, in line 40:4
extraneous input '{' expecting {<EOF>, 'Struct', 'Task', NL}
File ./PFDL_Examples/test.pfdl, in line 43:12
extraneous input 'dedent' expecting {<EOF>, 'Struct', 'Task', NL}
File ./PFDL_Examples/test.pfdl, in line 45:13
extraneous input 'dedent' expecting {<EOF>, 'Struct', 'Task', NL}
File ./PFDL_Examples/test.pfdl, in line 47:22
extraneous input 'dedent' expecting {<EOF>, 'Struct', 'Task', NL}
File ./PFDL_Examples/test.pfdl, in line 49:23
extraneous input 'dedent' expecting {<EOF>, 'Struct', 'Task', NL}
File ./PFDL_Examples/test.pfdl, in line 53:18
extraneous input 'dedent' expecting {<EOF>, 'Struct', 'Task', NL}
File ./PFDL_Examples/test.pfdl, in line 55:38
extraneous input 'Transport' expecting {<EOF>, 'Struct', 'Task', NL}
File ./PFDL_Examples/test.pfdl, in line 57:8
extraneous input 'dedent' expecting {<EOF>, 'Struct', 'Task', NL}
File ./PFDL_Examples/test.pfdl, in line 59:18
extraneous input 'dedent' expecting {<EOF>, 'Struct', 'Task', NL}
File ./PFDL_Examples/test.pfdl, in line 61:38
extraneous input 'dedent' expecting {<EOF>, 'Struct', 'Task', NL}
File ./PFDL_Examples/test.pfdl, in line 62:24
extraneous input 'dedent' expecting {<EOF>, 'Struct', 'Task', NL}
File ./PFDL_Examples/test.pfdl, in line 65:14
extraneous input 'dedent' expecting {<EOF>, 'Struct', 'Task', NL}
File ./PFDL_Examples/test.pfdl, in line 67:34
extraneous input 'Transport' expecting {<EOF>, 'Struct', 'Task', NL}
File ./PFDL_Examples/test.pfdl, in line 69:4
extraneous input 'dedent' expecting {<EOF>, 'Struct', 'Task', NL}
File ./PFDL_Examples/test.pfdl, in line 71:14
extraneous input 'dedent' expecting {<EOF>, 'Struct', 'Task', NL}
File ./PFDL_Examples/test.pfdl, in line 73:34
extraneous input 'dedent' expecting {<EOF>, 'Struct', 'Task', NL}
File ./PFDL_Examples/test.pfdl, in line 74:20
In general, it would be very helpful for users to remove these restrictions on namings and allow all namings to start with either an uppercase or a lowercase letter.
In productionTasks
it is not possible to define/declare input and output variables. As a result, additional tasks must be defined for the use of conditions, even if the condition is only applied to a single service. This makes the petri nets unnecessarily complex, as places and transitions are introduced that are not required for the process.
As possible solution could be to either declare variables outside of Tasks as global variables (data type of the variable, variable name)
cr_data_type cr =
{
parts_count = 3,
sheet_parts = [0,0,0]
}
Task productionTask
In cr:datatype
Loop i To cr.parts_count
Painting
In
cr.sheet_parts[i]
End
or it should be possible to define literal values as input for a production task, as allowed by all other defined tasks
Task productionTask
In
cr_data_type{
parts_count = 3,
sheet_parts = [0,0,0]
}
Loop i To cr.parts_count
Painting
In
cr.sheet_parts[i]
End
A similar concept should exist for output variables, so that the result of a pfdl process can be transferred to further processes
The documentation needs to be polished up, because some things are missing. For example more detailed descriptions for the examples or typos in the text.
To test the scheduling in a production environment we need Integration Tests and test files for the scheduling functionality. There are already some Integration tests that run a variety of PFDL files with the scheduler. Evaluate, whether it makes sense to include more Integration Tests (there could also be Integration Tests for the Parsing for example).
I receive the following TypeError for a PFDL description that includes a Counting Loop aafter a Parallel Loop. The error occurs when the counting Loop starts.
Traceback (most recent call last):
File "C:\Users\flo47663\Desktop\EE-SWAP\executionengine\start_execution_engine.py", line 42, in
main_loop.run_until_complete(ee.main())
File "C:\Users\flo47663\Anaconda3\lib\asyncio\base_events.py", line 647, in run_until_complete
return future.result()
File "C:\Users\flo47663\Desktop\EE-SWAP\executionengine\AuftragsAgentServer\execution_engine.py", line 75, in main
scheduler.fire_event(event)
File "C:\Users\flo47663\Desktop\EE-SWAP\executionengine/pfdl_scheduler\pfdl_scheduler\scheduler.py", line 181, in fire_event
if self.petri_net_logic.fire_event(event):
File "C:\Users\flo47663\Desktop\EE-SWAP\executionengine/pfdl_scheduler\pfdl_scheduler\petri_net\logic.py", line 127, in fire_event
self.evaluate_petri_net()
File "C:\Users\flo47663\Desktop\EE-SWAP\executionengine/pfdl_scheduler\pfdl_scheduler\petri_net\logic.py", line 99, in evaluate_petri_net
callback()
File "C:\Users\flo47663\Desktop\EE-SWAP\executionengine/pfdl_scheduler\pfdl_scheduler\scheduler.py", line 378, in on_counting_loop_started
self.loop_counters[task_context.uuid][loop.counting_variable] + 1
TypeError: unsupported operand type(s) for +: 'ParallelLoopCounter' and 'int'
The executed pfdl is:
Struct Order
order_id:number
stand:Stand_Segment
segments: Light_Segment[]
number_light_segments: number
End
Struct Stand_Segment
stand_shape:string
stand_height:number
stand_id:string
End
Struct Light_Segment
color: string
diameter: number
segment_id:string
End
Struct Raw_Material
blanks:Blank[]
blank_number:number
End
Struct Blank
blank_type:string
blank_id: string
part_id:number
End
Task productionTask
Parallel
manufacture_light_segments
In
Order
{
"order_id":1000,
"stand":{
"stand_shape":"plate",
"stand_height":3,
"stand_id": "Default"
},
"segments":
[
{
"color": "red",
"diameter": 5,
"segment_id": "Default"
}
],
"number_light_segments": 5
}
manufacture_stand_segment
In
Order
{
"order_id":1000,
"stand":{
"stand_shape":"plate",
"stand_height":3,
"stand_id": "Default"
},
"segments":
[
{
"color": "red",
"diameter": 5,
"segment_id": "Default"
}
],
"number_light_segments": 5
}
End
Task manufacture_light_segments
In
order: Order
Parallel Loop i To order.number_light_segments
manufacture_light_segment
In
order
Loop i To order.number_light_segments
Gluing
In
order
End
Task manufacture_stand_segment
In
order: Order
GetPartsFromWarehouse
In
ResourceAssignment
order
Milling
In
ResourceAssignment
order
End
Task manufacture_light_segment
In
order: Order
GetPartsFromWarehouse
In
order
Coating
In
order
End
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.