article

Jason Lightfoot avatar image
10 Likes"
Jason Lightfoot posted Jeanette F commented

Example Model: Opportunistic Parts Combiner Process (no ports)

1672351392559.png

This small model shows how to batch various parts together to form 'valid' combinations as they become available. This differs from a regular combiner where the component quantities are set in advance of the components being accepted in the combiner (often based on the type of item on port 1 entry). The valid combinations are shown as the quantities required for a number of products in a global table "ProductPartQuantitiesGrid":

1672351457585.png

By referencing the first picture and this table, you may be able to see that the model first constructs 4x Product2 followed by one product1 and a Product3. In the background process we are creating a token for each product which is then trying to pull all the parts needed while competing with the other products. This part of the process could be constrained in some way, for example where there is a target for the number of each product to produce over a time period.

So these tokens are being created in the Object Process Flow of the object we're calling OpportunityCombiner at time zero based on the table shown above:

1672352013659.png

Instead of the normal array generation this model creates a table label of the required parts for a product and stores it on the token. For Product1 that looks like this:

1672352174517.png

Tables aren't quite fully supported as labels yet so the syntax is a little odd when using them - in this case we do it like this:

Table(token.partsTable)[1]["Part"]  // evaluates to 'F'

Setting the labels up so that syntax works is a bit more complex. Note that the partsTable label is actually a pointer to the data table label on the token - called partsTableData. To get the view shown above you need to right click on the label partsTabelData and select "Explore As Table". Hopefully in the future this may be more streamlined if more people start using labels as tables.

The grid table doesn't play nice with sql, so another table creates itself at reset with a structure that is sql friendly:

1672352819574.png

That means the label table can be created with this query:

SELECT Part,Quantity FROM ProductPartQuantities WHERE Product=$1.product

What remains for the product token just involves getting the parts (a subflow) and them moving the array of all items to the combiner (a queue in the example); stacking them together and releasing to the conveyor before looping back to try and produce another. Below you see the main flow with four tokens - one for each product defined in the grid.

1672352717756.png

The subflow to get parts reads the token's table of parts for its product, and tries to get the correct quantities for each. This is similar to @Jordan Johnson 's solution for pulling from multiple lists, but is instead considering the table of parts from one list rather than arrays of resource lists and quantities.

1672353119596.png

The key aspects of this flow are that

  • 1. the first loop in the check section leaves the parts on the list, while the 'commit' section removes them
  • 2. we exit the check loop by using the pull timeout when we fail to pull the required quantity of a part type
  • 3. those that fail listen for pushes to the parts list
  • 4. success full product pulls insert the items pulled to the tokens label 'allItems' for later use.

Attached is the model. It should be relatively simple to transfer the process and tables to another model.

OpportunisticCombiner.fsm

combiner
· 4
5 |100000

Up to 12 attachments (including images) can be used with a maximum of 23.8 MiB each and 47.7 MiB total.

Helen avatar image Helen commented ·

Thank you @Jason Lightfoot,

It seems that is more complicated than expected. I'm trying to understand step by step and some questions arose.

  • You programmed Queue 1 as follows. Output > sent to port: First available and then Triggers On entry: push to parts (being parts a list). Is it the same to do Ouput> push to item list?
  • Why is the element that represents the combiner a Queue? Is there a specific reason for that?
  • Process flow:
    1. Why is it a time-event trigger?
0 Likes 0 ·
Jason Lightfoot avatar image Jason Lightfoot ♦♦ Helen commented ·

1) It's similar - items get on the list - but it's bypasses any queue events like batching that might control the release and therefor the send to port. You could argue it should be on the send-to-port, but that part is only for the example to have things put on the list - you can do that however you like, from wherever you like - multiple queues, racking etc.

2) The queue doesn't normally introduce extra events and places the item centrally. It could be almost any object - I considered using a basicFR but then I'd need to add some things. I choose 'do not release' for the send to port which allows that to be controlled by the process flow.

3) What to you mean by "Why is it a time-event trigger?" - you mean a scheduled source? That's just to create a token for each part type at time zero so that each can listen for the parts arriving.

0 Likes 0 ·
Chen avatar image Chen commented ·

Hi, do you have the flexsim 2021 ver. of this model since mine is outdated?

0 Likes 0 ·
Jeanette F avatar image Jeanette F ♦♦ Chen commented ·

Hello @Chen,

You can download the latest version of FlexSim from the FlexSim.com and open this model in the latest version. It will show a model limit but you can at least see the model run and how it works.


1 Like 1 ·

Article

Contributors

jason.lightfoot contributed to this article

Related Articles