question

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

How to push to list using code?

In my process flow, I have completed filling in the parameter of load and unload activity, and is now writing the conditional expressions in the beginning of token start. I query from the list and table firstly, then use if statement to determine which TaskType will AGV going to execute. I use token.agv.TaskType to record the task number agv gets. I assign the task agv is going to execute in Custom Code: Get Task activity. Now my AGV only do I/O to EQ(Input port to Processor), then it stops. However, it should chooese to execute I/O to Queue (TaskType2) next base on my if statement. Since the material from Inputport has two possible destination. I hope to push the material to 2 different lists in the Custom Code: Get Task line 39, 40, 53, 54, but fail to push material to list using code. The token is not successfully assigned the TaskType value it is going to execute later. For materials from I/O to Processor will be pushed to itemlist2; for materials from I/O to Queue will be pushed to itemlist4. I didn't use push to list activity to do this, because I don't have tokens in process flow that represent materials, otherwise perhaps it would be simpler to use activity.


The if statement part of my code is used to query if Processor/Queue is available. My script to query from list and table are at the left hand side custom code: Query, the conditional expressions are written in the middle below the Source: AGV token activity.

Also, the following error exception was from Process Flow in the activity called "custom code: Update EQ Table". The problem seemed to be coming from line 56 where I try to have "n/a" assigned to a number field. But I cannot understand why String cannot be written into the table.

time: 582.000000 exception: FlexScript exception: MODEL:/Tools/ProcessFlow/ProcessFlow_02/Custom Code: Update EQ Table>variables/codeNode

Thank you!

0813-agv-write-to-table.fsm

FlexSim 21.1.4
flexsim 21.1.4custom codepush to list
5 |100000

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

1 Answer

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

Here are some things that are going wrong in your model at the moment:

1. In "Get Task" you assume that there will always be an entry for the available EQ or Queues by assigning "Table("countAvailableResource2")[1][1]" as a variable. That table will not exist if no entry is on the list, leading to an error.

You don't actually need to clone the query result to a table first. Instead of using "COUNT" in the query I would simply have it select all fitting entries. The value you are looking for will then be the number of rows in the query result table, that you can assign to the "value" variable.

// Example for one type only
Table myTable  = Table.query("SELECT resourceType FROM FRList_AvailableResource WHERE resourceType = 0 ")
Variant value = myTable.numRows; //空的Queue


2. In the "Update X Table" activities you are trying to read labels on items that don't exist.

Using

Table("QueueTable")[j][10]=groupmember("QueueGroup",j).first.labels.assert("Registered").value;

(or something similar) assumes that there is an item inside the respective object. At other points you check that this is the case by checking the state of the queue or processor. Towards the end of "Update Queue Table" there are three lines (as above) where such a check is not done, leading to an error.

In "Update EQ Table" there is also one case of this. For one condition you wrote

if(groupmember("EQGroup",i).stats.state().value == 2 || 4) 
{
Table("EQTable")[i][7]=groupmember("EQGroup",i).first.labels.assert("enterEQtime").value;
}

The "4" is interpreted as "true", meaning the OR-statement will always return true.

I assume what you meant to write is

if(groupmember("EQGroup",i).stats.state().value == 2 || (groupmember("EQGroup",i).stats.state().value == 4)


3. The processors push themselves to the wrong list in the Exit trigger (ItemList3 when it should be FRList_AvailableResource), if I'm not mistaken.


4. You always unload to "token.pulledavailableResource". For tasktype 3 this will still point the last used queue or processor as the label is not reassign to point to Queue5.

· 9
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, thank you for your detailed explanation.

I have fixed you mentioned above, but AGV doesn't start it's action, and I tried to give TaskType4 to AGV directly, AGV only execute tasktype2 and tasktype3 in simulation run. I wrote the value of availableResource out and check again with my if statement logic. I think there should be no problem, but my Custom Code: Get Task still cannot give AGV a right TaskType.

0817_agv write to table.fsm

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

The "Get Task" code will currently always end up assigning tasktype 3 if no processor is available (value2 == 0). Either switch the order of the else-if conditions for tasktype 3 and 4 around or add another condition that "value" should also be zero to assign type 3.

1629187221037.png

I also don't quite understand the purpose of checking whether "value" is larger than zero before assigning tasktype 2. Why is it important that there is a free "OHB" queue for that task?

By directly assigning the first subnode of "Queue4" the code assumes that there will always be an item in the I/O queue. If that should ever not be the case FlexSim will throw an error. Before you assign an object like that, you should always check if one actually exists. For example with:

if(model().find("Queue4").subnodes.length)
{
     List("ItemList4").push(model().find("Queue4").first);
}

One more thing: I guess you might plan on scaling the model up once it works properly. Be aware that by always pushing the first item in the queue to the list, you might end up pushing the same item to the list twice if a second AGV/token executes the code before the first item was loaded from the queue. To circumvent this, you could mark item that were pushed to the list with a label. Then, instead of pushing the first item in the queue, you loop through the items (subnodes) until you find one without that labelvalue.



0 Likes 0 ·
1629187221037.png (29.5 KiB)
shanice.c avatar image shanice.c Felix Möhlmann commented ·

@Felix Möhlmann I made mistake in the "value2==0", I've added "value4" to record the number of blocked processor, which is used to find the tasktype3(Processor to I/O).

I would scale my model up once it works properly. For 2 AGVs system, I have 2 problems. First, I have added another AGV into my model, and there's error that two AGVs pull same box. I wrote my loop code in "Get Task" code, and hope this could prevent from repeatedly pushing the same box to list. But 2 AGVs seem not work properly.


擷取.png


Second problem is I tried to use "Object process flow", and I'm not sure if I should create 1 or 2 token in the source. If I have already attached instances into process flow, is it necessary to use Acquire Resource activity? I'm not sure if this would lead to error.

0818_agv write to table.fsm

0 Likes 0 ·
擷取.png (24.8 KiB)
Show more comments
shanice.c avatar image shanice.c commented ·

Hello, @Felix Möhlmann, I sincerely appreciate your help. This is my first time using process flow to build custom logic. This model is the first area of my plant, there are still second and third area to build then. However, with your help, I could get my model move forward step by step. Also your instructions in programming (for those mistakes I made) does help me. All the best!

0 Likes 0 ·