question

Jon Abbott avatar image
1 Like"
Jon Abbott asked Jon Abbott edited

Can variable operator productivity and/or availability be modeled?

Most of our simulation models run for a year or two in simulated time. When operators are assigned in the model, their schedules do not change throughout the duration of the simulation. We would like the ability to assess the affect of adding new operators that start out not fully productive, but become more productive over time. We also would like to assess the affect of current operators being less productive as they train new operators.

For example, Operator 2 would start out in January at 25% productive, then in April they would become 50% productive, in July they become 75% productive, and finally by October they are 100% productive. Likewise, Operator 1 will be training Operator 2 and is therefore 75% productive until Operator 2 is fully proficient. Our team has devised two potential options for implementing this, but we are uncertain of the code necessary to accomplish either one:

  1. Create time tables to represent each level of productivity (25%, 50%, 75% and 100% of full time). Then, have code running during the simulation that periodically checks the clock and swaps out the tree entry for the operator's time table.
  2. Assign a productivity label to operators, with a number such as 0.25, 0.5, 0.75 or 1.0. Then divide each processor setup and process time that uses an operator by that label value. That way the process times would scale as a function of operator proficiency. This would also involve adding a fail-safe so that if no label were present on the operator, it would divide by 1.0. There would also be code required to check the clock and update the operator's proficiency label value at periodic intervals.

We are thinking that option 1 may not be as effective as option 2. We are also open to other suggestions. More than anything, we would need to know what code can be used to check the clock (without bogging down the model too much) and change the operator's label value or time table. Thanks in advance for any help you can provide.

FlexSim 16.0.5
learning curveoperator schedule
5 |100000

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

Logan Gold avatar image
2 Likes"
Logan Gold answered Joerg Vogel commented

Here is a quick example model to show you how you could use different efficiencies on an Operator as the model progresses over time: functiontable-example-16-2.fsm

The model also uses a function table to determine Operator efficiency, which was another question asked through email, but is related to this same problem so I wanted to include it all in the same place.

The order of events on a Processor makes it so the process time is calculated before requesting an Operator to use for that process, so there's not exactly a straightforward way to base the process time on a label of a specific Operator unless you know which Operator will be used before the process time is calculated.

One way to do this is to use Process Flow like in the attached model. The model still utilizes the Processor for most processing events instead of just being a visual tool, but if it makes more sense to use Process Flow for all of the logic, that can be done using the same function table logic. Apart from the transportation of the flowitems, the Process Flow logic changes a label on an acquired Processor (named efficiency) which is in turn used to calculate the process time.

I also use a label on each Operator to determine which column we should look at in the Global Table named FunctionTable when that Operator is being used for process time. OperatorA uses the second column and OperatorB uses the third column. The table itself has the first column setup with different model times. These values are in time units regardless of which time units the model was built with. So in this model, the time units are seconds and the first column is the number of seconds between splits. The values in the rest of the columns are the efficiency values to use for each Operator corresponding to the splits in model run time.

With the Process Flow, I create tokens when a flowitem enters the Queue. Then, I acquire one of the Operators and one of the Processors to use. The Operator travels to the Queue, picks up the item, then travels to the Processor. After this last travel task, I use custom code to make the necessary change to the Processor's efficiency label. This custom code uses a User Command called getEfficiency to determine the efficiency that will be used, which is based on the current time and the Operator that is being used. You can look at getEfficiency's comments to get a better idea of how it works.

Once the efficiency label on the Processor is set, the next activity in Process Flow unloads the item to the Processor and processing begins. Then, the token waits for the item to leave the Processor before releasing the Operator and Processor to start the process over with a new flowitem.


· 1
5 |100000

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

Joerg Vogel avatar image Joerg Vogel commented ·

If an operator transports an item and process this item, too, you can quite easy set the productivity process time. In the transport tasksequence you send after loading of the item a message to the operator, which contains a reference to item. In the OnMessage trigger of the operator you set a label value in the item to the future process time, because the operator knows how productive he is and though the process time is going to be. The processor reads this label in the process time function to return this label as the process time.

0 Likes 0 ·
Jon Abbott avatar image
1 Like"
Jon Abbott answered Jon Abbott edited

Thanks everyone for all the great information. I ended up using a combination of @Logan Gold's answer from above, as well as @Jeff Nordgren/@Matt Long's model from a different thread to accomplish Option 2 above. It enables productivity (which we also call proficiency or efficiency) to be modeled per operator over time. The existing model we are implementing this for is large and entirely 3D-based, so I sought to make the fewest possible changes to successfully enable this functionality. The attached example model implements this functionality without requiring a Process Flow. The following changes were necessary to make it work:

    1. Add specific code in the OnReset, OnMessage, OnProcessFinish triggers on processors (see example model for the code).
    2. Add a very small but non-zero setup time to each processor and request the operator. Also enable the setup operator to be used for both setup and process. Note that these changes are required in order for the processor to summon the operator and correctly retrieve and apply his or her proficiency level before starting the processing. If the processor requires setup time without an operator present, or a different operator for setup and processing, or more than one operator, this proposed solution will not work as-is.
    3. Add labels in each processor for the task executor proficiency and task executor ID/name (note: proficiency is required but ID is optional).
    4. Add a getlabel statement to the process time that divides the existing process time by the task executor proficiency that is stored in the processor label.
    5. Add a table called OperatorProficiencies that captures the proficiency level at different times in the model.
    6. Add multiple user commands (see example model for each).

    I used Logan's "getEfficiency" user command to return the proficiency for the operator at the time it is called, and it interpolates when the process starts between two times listed in the table. As a fail-safe, proficiency is kept at 100% in the event of an error. One improvement I made was to allow the proficiency table to be referenced by operator name, which makes it more intuitive to scale this solution to larger numbers of operators. I renamed this user command to "SaveProficiency". This model was built using FlexSim 16.2.

    Update on 10/25/16: Added code to the OnMessage trigger to check that the passed in task executor is in fact a task executor. While this does not affect the example model at all, it does prevent non-task executor objects in more complex models from mistakenly changing the TEid and TEproficiency labels when messaging a processor.


    5 |100000

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

    Joerg Vogel avatar image
    1 Like"
    Joerg Vogel answered Jeff Nordgren commented

    That isn't possible to adjust the productivity directly, because not a operator goes to a processor and initiate the work. Flexsim works different. The flowitem initiates the working. An approach is to lure the operator to the processor for example by the setup. The setup time is very short, but as the operator goes to processor he sends a message to the processor. Though the processor gets a reference to operator and looks into a productivity label inside the operator. Then the processor calculates the Processtime depending on this information.

    The Multiprocessor has the ability to change the process times several times. At each process step you can adjust the productivity or better the next Processtime.

    · 2
    5 |100000

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

    Joerg Vogel avatar image Joerg Vogel commented ·

    @Jeff Nordgren has answered how to send a message to the processor to identify the operator here. You find the information in the manual chapter Task Sequences in the references, too. Then you look for the Task Type sendmessage.

    0 Likes 0 ·
    Joerg Vogel avatar image Joerg Vogel commented ·

    Just a possible idea: If the process time is set through a list and a back order is created depending on the involved operator then this would be a direct approach in Flexsim. But my knowledge isn't at this stage to test such an approach.

    0 Likes 0 ·
    Sam Stubbs avatar image
    0 Likes"
    Sam Stubbs answered Kathryn McNeal commented

    In order to check the clock, you can always call the time() function which will return the current time of the model. You can use a global variable to store that time, and conditional logic to check against the values in the table. Obviously the simpler you can make it, the less potential it has for bogging down your system.

    I think that you are correct in your assessment that option number 2 will be more effective. At least it seemed more intuitive in my opinion. It seems easier to add or reduce the number of operators as you need, if the times are all just pulled dynamically from a label on the operators in the first place.

    5 |100000

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