question

Craig DIckson avatar image
1 Like"
Craig DIckson asked Ben Wilson commented

set TE speed using property table

I would like to use a property table to set the speed of all of the task executers in my model. I seem to be able to change the corresponding cells of the table, but the new speed does not propagate to the TEs themselves.

string sCell;
double dInchesPerSecond = Table("tableSpeeds")["ANT_SPEED""]["VALUE"];

for (int iANT = 1; iANT <=  MAX_ANTS; iANT ++){
    sCell = "Tools/PropertyTables/TravelProperties1>variables/table/" + numtostring(iANT) + "/2"; // speed is in the second column
    Model.find(sCell).value = dInchesPerSecond;
}

What else am I missing?

(Anthony, I know there are other ways to do this, am pretty interested because apparently property table will now become the main way to manipulate conveyors due to the death of conveyor types in FS21.)

FlexSim 20.2.3
flexsim 20.2.3property tablestask executer variables
· 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.

Ben Wilson avatar image Ben Wilson ♦♦ commented ·

Hi @Craig DIckson, was anthony.johnson's or Matthew Gillespie's or jason.lightfoot's answer helpful? If so, please click the red "Accept" button at the bottom of one of their answers. Or if you still have questions, add a comment and we'll continue the conversation.

If we haven't heard back from you within 3 business days we'll auto-accept an answer, but you can always unaccept and comment back to reopen your question.

0 Likes 0 ·
anthony.johnson avatar image
1 Like"
anthony.johnson answered anthony.johnson edited

Property tables are intended to be a starting point that allows you to programmatically update object properties. By pressing the SQL button in the property table UI, you can see the query that corresponds to that property table. Then, you can use that query (specifically the WHERE clause) to create your own SQL UPDATE query. For example, the query below should do what you are intending, i.e. set the MaxSpeed property on all task executers based on a lookup from the tableSpeeds table.

double dInchesPerSecond = Table("tableSpeeds")["ANT_SPEED""]["VALUE"];
Table.query("UPDATE Objects() SET MaxSpeed = $1 WHERE 'TaskExecuter' IN Classes", dInchesPerSecond);

You could also do an inner join, to set multiple different values based on different entries in the tableSpeeds table. You could add a "Group" column to your tableSpeeds table, to distinguish which objects should have their speeds set to what values.

Then you could execute a query like the following:

Table.query("UPDATE Objects() INNER JOIN tableSpeeds ON tableSpeeds.GROUP IN Groups SET MaxSpeed = tableSpeeds.VALUE");

This goes through the 'Objects()' table, i.e. all objects in the model, then matches the object with the row in tableSpeeds that has the group that the object is a member of, then sets the MaxSpeed property of that object to the value in tableSpeed's VALUE column.

Also, as of 21.1, you can integrate property tables directly into your UPDATE query:

double dInchesPerSecond = Table("tableSpeeds")["ANT_SPEED""]["VALUE"];
Table.query("UPDATE TravelProperties1 SET MaxSpeed = $1", dInchesPerSecond);

Also as of 21.1, property tables will be properly integrated into the Table class. So you can essentially do your for loop.

double dInchesPerSecond = Table("tableSpeeds")["ANT_SPEED""]["VALUE"]; 
Table propTable = Table("TravelProperties1");

for (int iANT = 1; iANT <=  propTable.numRows; iANT ++){
    propTable[iANT][2] = dInchesPerSecond; 
}

Although I personally feel like using Table.query() is cleaner. Property tables are built on, and integrate deeply with, FlexSim's SQL engine. So, when you're interacting with property tables, it's useful to shift your paradigm to thinking from a SQL perspective. If you can do that, and grasp some basic SQL concepts, both updating and querying data becomes pretty easy, and avoids having to write a ton of for loops.

And, since the cat is out of the bag, yes, we're working on a "templates" feature. When you create an "instance" of a template, by default the instance will "inherit" most properties from its template, so if you change them on the template, those changes will automatically propagate to all instances. However, you can override any and all properties on each instance as needed, include things like length, or whatever you want. Thus, what is inherited and what is overridden is defined by you the user. This feature is what the conveyor types should have been, but were really badly designed.


1616783345050.png (6.3 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.

Matthew Gillespie avatar image
1 Like"
Matthew Gillespie answered Matthew Gillespie edited

Property Tables are a user interface for quickly viewing and editing properties on multiple objects at once. For example, changing the Width and Horizontal Length of multiple conveyors:

In 21.0 and earlier, property tables can't be used programmatically. If you want to programmatically update multiple objects you should loop over the objects you are interested in. For example:

Setting the speed of all objects in the MyTEs group

Group group = Group("MyTEs");
for (int i = 1; i <= group.length; i++) {
     group[i].setProperty("MaxSpeed", 3);
 }

Setting the speed of all TE objects in the model

forobjecttreeunder(model()) {
     if (isclasstype(a, "TaskExecuter"))         
         a.as(Object).setProperty("MaxSpeed", 1); 
}

As of 21.1, you can use an UPDATE query with a property table to programmatically update objects.

double dInchesPerSecond = Table("tableSpeeds")["ANT_SPEED""]["VALUE"]; 
Table.query("UPDATE TravelProperties1 SET MaxSpeed = $1", dInchesPerSecond);

Also, you may be interested to know we are developing a new feature for 21.2 where you can create a template object and make other objects instances of the template object. Then changing a property on the template object will automatically update that property on all the instances of the template object.


propertytable.gif (348.9 KiB)
· 3
5 |100000

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

Craig DIckson avatar image Craig DIckson commented ·

@Matthew Gillespie

You suggested that:

"If you want to programmatically update multiple objects you should loop over the objects you are interested in."

That is exactly what I was trying to do, by looping through the property table, rather than going though the extra steps of making and populating a new table when the property table already existed with the needed information. I have to say that I am very surprised that property tables can be changed by the user but not by code; I cannot think of any other example of this distinction in FlexSim. Was this a design decision or is there a technical reason? Also, can a property table be read programmatically?

The code for looping though groups will be helpful though. This feels like it ought to be something in a tutorial somewhere. One thing that I have struggled with is finding a list of the available property names for various objects. Usually I end up using the eyedropper, but that frequently returns deprecated suggestions.

I am indeed very interested in the template object functionality. I have one absolute need regarding how this works with conveyors: the template object should apply to conveyors of any length, i.e. the length can't be part of the template. It will be completely useless if I need a separate template by bed length.

0 Likes 0 ·
Jason Lightfoot avatar image Jason Lightfoot ♦♦ Craig DIckson commented ·

I would add that any property that has been overridden in the instance should be preserved by default. This can be done just by comparing the value with that of the template. The you have full customisation control.

0 Likes 0 ·
Matthew Gillespie avatar image Matthew Gillespie ♦♦ Craig DIckson commented ·

@Craig DIckson Yes, it's by design that property tables work that way. That said, you can programmatically do the exact same things that the property tables are doing. From the documentation on property tables:

Property tables are an easy-to-use tool for viewing and managing object properties. At their core, however, property tables are just a user interface wrapper around FlexSim's powerful SQL capabilities.

We have documented lists of all object properties on the user manual page for each object. For example, the properties of conveyors.

Yes, the template instance objects will be able to override specific properties that they don't want to inherit from the template. So you should easily be able to have conveyors that share all their properties except that each has its own position and length.

0 Likes 0 ·
Jason Lightfoot avatar image
1 Like"
Jason Lightfoot answered Craig DIckson commented

If you're reading the speed from a table why do you need to write it to a property table - just set the property on the object itself using the setProperty method.

The property table is just a view of the model in table form to help people work with large, unstructured models with unmanaged objects.


· 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.

Craig DIckson avatar image Craig DIckson commented ·

Jason, I do know how to do it for individual items; I was trying to make simple, efficient and relatively unbreakable code by not hardcoding things and using the provided structures (i.e. property tables).

I really don't understand the the usefulness of property tables if I can't use them to set parameters. Not being able to set things via property tables concerns me a lot WRT conveyors given the demise of conveyor types: I was led to believe that property tables could be used to serve more or less the same function, but if I cannot set from a table that's not the case at all.

(As an aside, while I am ranting let me also say that writing simple clean code would be much easier if FlexSim numbered items/objects in a predictable manner based on similar items/objects rather than (I assume) on something to do with the tree depth. Of course I could rename things, but in a large model that is an unnecessary pain in the a**.)

0 Likes 0 ·