question

shanice.c avatar image
0 Likes"
shanice.c asked shanice.c commented

Could I write token.label in list properties field expression?

I'm currently writing a process flow that is from product's point of view. What I'm doing in my flow is to create a task, then the flow will next find an AGV for each task. A product is "token.product".

Firstly, I'm a kind of confused how to connect an item in 3D model to a process flow token. I use On event trigger and use "match" to get the reference from the item in 3D model. But I'm not really sure the difference of using"assign" and "match". Is "assign" only update value whenever status changes from 3D model ? And using "match" could both update any status changes from 3D model and process flow?


Secondly is about getting value. Now,I'd like to use process flow randomly find one AGV for a product, may I do it like below? There are 6 AGVs in my model. I use duniform to get a number, each number correspond to a TaskExecuter. After this, I also want to write the AGV that each product gets( "token.product.transport") to a list field(which is "List for ALL Product" in model), but it seems "token.product.transport" cannot be read, result always get 0.

圖片1.png

p2.png

This is where the custom code mentioned above. Thank you!

p3.png


0902-product point of view.fsm

FlexSim 21.2.0
listflexsim 21.2.0
圖片1.png (47.9 KiB)
p2.png (58.8 KiB)
p3.png (270.6 KiB)
5 |100000

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

Felix Möhlmann avatar image
1 Like"
Felix Möhlmann answered Felix Möhlmann commented

Every event has certain parameters associated with it. For example the entry trigger of the queue has the entering item and the port rank through which it entered as parameters.

If you choose "assign" then that value of the event will be written to the label you type into the "Label Name or Value" field.

If you choose "match", then the value will be compared to that of the token label and the token only finishes the activity if those two match - hence the name. This can be useful if you want to wait for certain item to finish processing for example.

More info can be found here:

https://docs.flexsim.com/en/21.1/Reference/ProcessFlowObjects/SharedProperties/SharedProperties.html#label


Yes, you can get a random AGV that way, but be aware that multiple items might be assigned to the same AGV in close succession that way.

If you only want to assign available AGVs, it would be better to define them as a process flow resource (easiest by grouping them and referencing that group in the resource) and have them be acquired that way. To get a random one you can use "ORDER BY RAND()" in the query of the "Acquire Resource" activity.

1630579943601.png


The list doesn't have a reference to the token that pushed the value onto the list, only to the value that was pushed (and the puller token, when a token attempts to pull something from the list).

You set the label on the item itself though, so you can just use another label field in the list.

1630579904851.png


1630579904851.png (10.3 KiB)
1630579943601.png (14.1 KiB)
· 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.

shanice.c avatar image shanice.c commented ·

Hi, @Felix Möhlmann, for the way to get random AGV, is "ORDER BY RAND()" also has a distribution? Because I still hope using the random could still remain each AGV workload balance.


Here I would explain a little bit why I let product get AGV randomly. I know it's a little bit counterintuitive. Last few weeks ago you have helped me with process flow model that was built from AGV's point of view. Previous simulation process flow building perspective is more reasonable to me, because just like you say if I get AGV randomly, multiple items might be assigned to the same AGV in close succession. But my manager and our customers would consider conditions that are usually not so logical compared to I generally think. For example, they said in real plant, operators would give AGV tasks, rather than AGV look for it's job after finishing one on it's own. Although the later way does make sense. Anyway, this why I start off a new process flow with opposite perspective, to simulate somewhat not so regular conditionals they have with this kind of point of view, so that we could test the AGV group's ability to transport and the performance of Equipment(which is the most important thing company care about).

0 Likes 0 ·
Felix Möhlmann avatar image Felix Möhlmann shanice.c commented ·

ORDER BY RAND() should have equal chance for any resource to be acquired. But if you use the AGVs as resource, then each one could only be assigned to one item at a time anyway. Other items would have to wait until an AGV becomes available again and the work balancing would thus happen kind of automatically.

You could also mix your approach with the resource. Assign an AGV to each item before they enter the "Acquire" activity, and then put "token.product.Transporter" into the query field so they only pull the pre-determined AGV. This would keep the distribution from your code but make sure that AGVs can't receive multiple conflicting orders at the same time.

Sample model for acquiring a specific resource object:

Pull_Specific_Object.fsm


0 Likes 0 ·
shanice.c avatar image
0 Likes"
shanice.c answered shanice.c commented

May I first ask what should be used in yellow place to get the AGV name? Value is not correct, I have used .valueString and .name, still haven't get the value.


擷取.png


擷取.png (60.4 KiB)
· 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.

Felix Möhlmann avatar image Felix Möhlmann commented ·

When using ".labels.assert()" or ".labels[]" you reference the node of the label in the tree. Putting ".name" after it thus returns the name of the label. ".value" will return the balue of that node.

To get the name of the AGV you would use

tempProduct.labels.assert("Transporter").value.name

You possibly might have to put ".as(Object)" in, so "name" is recognized as a valid command

tempProduct.labels.assert("Transporter").value.as(Object).name


If you are using the dot-syntax (without ".labels") you can also get the name with just

tempProduct.Transporter.as(Object).name

, as using this syntax references the label value directly, not the node.


Your screenshot suggests you are trying to assign the reference to the AGV as its name (?) That won't work. If you want to print the name in your last line, just replace "token.product.Transporter" with one of the ways to get the name from above.

print("printout Taskexecuter: " + tempProduct.Transporter.as(Object).name);
0 Likes 0 ·
shanice.c avatar image shanice.c Felix Möhlmann commented ·

@Felix Möhlmann I'm sorry for being late in replying. I think I have some problems with how to synchronize labels of 3D flow item and token.product.

1. I used On event trigger so that one token is correspond to one flow item. There are some labels for one product, some values will be changed in 3D model, others will be changed in process flow. So I think I'll have to synchronize labels. You have taught me to set the label on the item itself, I try to assign all labels that a flow item has in 3D model to Assign Labels of All Info. activity of process flow. Like to picture.

label.png

But I don't quite understand why doing this way, it could get the value of token.product.labelname. Ex: I print out token.product.ID, the product ID 1~20 is written out. Is it because of the using match in the beginning of source?


id.png



2. Some label values are changed when following the on triggers event happen in 3D model. I'm confused how to synchronize 2 labels? Or basically I shouldn't try to control labels by using 3D model and process flow at the same time? I've asked our country distributor, they suggested me not to give logic by using 3D model and process flow at the same time, or it may cause error.

3. After assigning the labels correctly, I would like to synchronize the token.product.Transporter in process flow to item.Transporter in 3D model. That's also what I did in line 41-42. Line41 I would like to know which product is this token refer to, and then give it to the 3D model label. I tried again with reference the Transporter(Transporter that product gets), also tried to print out, but still nothing is written out. I'm afraid it's due to mistakes of labels previous assigned .

p1.png


0906_product point of view_autosave.fsm


May I also know what is "as(Object)"?

0 Likes 0 ·
Felix Möhlmann avatar image Felix Möhlmann shanice.c commented ·

1. The event triggered source is set to "assign" the triggering object (the one that enters QueueIO) to the label "product" on the created token. Writing

token.product.Transport = ...;

is the same as using two steps:

Object item = token.product;
item.Transport = ...

If you didn't use the "assign" function there would be no connection between the token and the item.

2. I don't know of any easy way to automatically sync to labels to each other. You would have to manually update both each time a change is made. The question is: Do you actually need to copy the labels to the token? You are referencing the item labels in your code anyway, as far as I can tell. Is there any particular reason for why you want to have the labels on the tokens itself?

If you want to keep it this way, you can create a label on the item that refers to the token and use it to update the token label as well, when the item label is changed by a trigger event.

1630910850200.pngThen you can use "item.Token.<insertLabelName>" to set the token labels on 3D object triggers.

Not mixing 3D and process flow logic mostly refers to using input/output-connections while also controlling item movement through the process flow. This can easily lead to conflicting tasks and unwanted behaviour. Setting labels in one or the other is fine mostly fine though.

3. As said in point 1: "token.product" already refers to the item. Your "token.product.Transporter = Model.find..." is creating the label "Transporter" on the item. There is no need to assign it again.

Apart from that; due to some faulty code from your last post, the names of the task executers got deleted. "Model.find..." thus can't find the objects under the given names and nothing is assigned to the label. You have to rename the task executers to their previous names.


Other things I noticed/reasons for errors:

- In the "Custom Code: Update Queue Table" in the "Object" process flow, the last active line of code assumes that there is an item in the respective queue. If that's not the case this leads to the error:
"time: 1.000000 exception: FlexScript exception: MODEL:/Tools/ProcessFlow/Object/Custom Code: Update Queue Table>variables/codeNode"

- "Code: 1)Look for Destination, 2)Determine TaskType" is using the label "ResourceRequired" on the item and "ResourceType" on the QueueIO (line 11 and 12). These don't exist as of yet.

- In the same activity, you started a multiline comment (/*) at the bottom but didn't end it with (*/) leading to a compiler error.

- Another compiler error comes from leaving the "default" option in the "Determine CST TaskType" decide activity empty.

0 Likes 0 ·
1630910850200.png (12.6 KiB)
Show more comments