FlexSim Knowledge Base
Announcements, articles, and guides to help you take your simulations to the next level.
Sort by:
We recently had a customer ask how to draw a flow item label on the flow item object. I thought that this information would be useful to other FlexSim users as well. In the 3D model, drag and drop a Text visual from the Library. Select the text in the 3D model, then copy it to the clipboard using Ctl + C Go to the Toolbox tab, open the FlowItem Bin, and double click the Flow Item of interest. Right click the 3D flow object, and click "Explore Tree" Click in the white space underneath the Flow Item's node, and use Ctl + V to paste the text as a subnode to the flow item. If you zoom out in the Flow Item's 3D view, you will see the text. You can double click on the text and use the General tab to position it wherever you would like. Double click the 3D Flow Item. Underneath the Labels tab, select the green plus sign to add your label. In my example, I added a number label called "Type" with a default setting of 0. Click "OK". Double click the text that you added in step 5 and 6. Underneath the Display tab, click the custom code button next to Text Display. Within the custom code type something like the following: /**Custom Code*/ Object current = ownerobject(c); treenode textnode = param(1); textnode.value = "Type: " + string.fromNum(current.up.Type); //Note: If your label is called something other than "Type", make sure to replace it in both places. Click out of the "FlowItem Bin" tab and back into the "Model" tab. Double click the source where your Flow Item is being created. Underneath the Triggers tab, add an On Creation trigger. Click the green plus next to the On Creation trigger. Hover over Data and select "Set Label". Make sure the text next to the Label field matches the text of the label you set in step 7 and 8. By following these steps, each Flow Item will have a text label that displays the Flow Item label next to the Flow Item object. Please see the attached gif for a demonstration. flowitem-label.gif
View full article
Here on Answers it's often helpful to post code in a question or an answer. When you do so, there are certain steps that should be taken to avoid being blocked by Answers' internal security mechanisms. This article describes the proper way to submit code without arousing suspicion from our threat detection software. Some of our customers are all too familiar with the screen below after asking a question or adding a comment that includes code. What is Cloudflare? Cloudflare is a 3rd party threat detection software specifically designed to detect malicious code/software that may threaten a website. Once you've seen this screen above, there is no way for us to un-block you, as it is an automated 3rd party software. Unfortunately, at this point you have to wait a variable amount of time until Cloudflare decides your IP address is no longer a threat and you will again be allowed access to answers.flexsim.com. What am I doing wrong? This warning usually presents itself when code has been typed or pasted directly into the body of your post, like this: How do I properly format my code? First paste or type your code into the body of your post. Then, highlight your code and click the Code button in the toolbar. It looks like this: < > How can I tell if my code is properly formatted? After highlighting your code and clicking the code < > button, you will see that your code now has a border and light background: Remember, if you have multiple blocks of code, you can select just the code you want to be grouped together in the first block, hit the code button in the toolbar, and then select the second group of code and again hit the code button to make the second code block, etc. After you submit your post, you will see your code formatted with syntax highlighting, a mono-spaced font, and the lines numbered, like this: Conclusion Adding code to your post is an essential task for many of our customers. If you follow these guidelines, you should be able to avoid being blocked and ensure you have uninterrupted service on our answers site. If you feel you have properly entered code and are still being blocked, please inform us and include the code and method of formatting you were using when you were blocked. We'll gladly look into it. As a fallback, you can take a screenshot of your code and add it to your post as an image, but still let us know there was an issue, and we'll look into it. Finally, if you're in a hurry and Answers troubles are keeping you from getting the help you need, remember to contact your local FlexSim representative directly by phone or email.
View full article
FlexSim 2021 Update 2 Beta is now available (Updated 26 July 2021) To get the beta, log in to your account at https://account.flexsim.com, then go to the Downloads section, and click on More Versions. It will be at the top of the list. The More Versions button does not appear when logged in as a guest account. Subsequently the beta is available only to licensed accounts and accounts that have a license shared with them. Learn more about downloading the best version of FlexSim for your license here. If you have bug reports or other feedback on the software, please email dev@flexsim.com or create a new idea in the Development space. FlexSim 21.2.0 Release Notes Added a Template system for inheriting properties from other objects. Added new manipulation handles for moving, rotating, scaling, and connecting objects in the 3D view. Added ability to delete connector lines. Added a StateTable object. Added a getstatetableutilization() command. Added a Pass-through parameter type. Added a checkbox so transporters can move their forks separate from traveling. Added more Task Executer shapes. Improved treenode.getPath() to return a relative path to nodes that aren't a direct ancestor. Added a Frustrum Culling checkbox in Visuals. Agent Added an AgentSystems property. AGV Allowed the user to define some basic routing cost multipliers, including: An option to divide by speed, allowing for fastest path routing (instead of shortest path) An option to define a custom path-based multiplier to the cost Added Path Conditions, which allow you to "close" certain paths, based on either model state or agv state, etc. Added a Prioritize Control Point Lookahead option. A* Added the capability to have oblong grid node sizes. Allowed barriers to be inside visual tools. Added the ability to add dynamic barriers to the A* system. This is done by calling AStar.navigator.addDynamicBarrier(), then AStar.navigator.removeDynamicBarrier() to remove those barriers. Added several triggers to A* objects: AStar.Navigator: OnGridChange: called when dynamic barriers are added or removed AStar.Traveler: OnCalculatePath: called just before a traveler's path is being calculated AStar.Traveler: OnNavigatePath: Called just before a traveler runs the algorithm to define kinematics and cell allocations for traveling its path. Also allows the ability to override the default behavior and define your own. Made several additions to AStar.Traveler API, AStar.Navigator API, etc. Added a TravelPatterns property. Backwards Compatibility Note: The following changes may slightly change the way updated models behave. Improved the deadlock recovery algorithm. Now it will add each traveler in the deadlock, as well as any travelers that are waiting on those travelers, as dynamic barriers. Then it will go through each traveler in the deadlock, remove it from the dynamic barriers, add any additional travelers that are adjacent to that traveler as barriers, then try to recalculate the path to the traveler's destination. If it finds a traveler that can still travel all the way to its destination, that traveler will be rerouted. Otherwise, if it finds a traveler that can travel at least on grid square, it will reroute that traveler. Otherwise, it will give a notification of unrecoverable deadlock. GIS Added the GIS module to the Flexsim Installer. Process Flow Added a ProcessFlows property. Added a ProcessFlowVariables property. Backwards Compatibility Note: The following changes may slightly change the way updated models behave. Removed instance object editing from Object Process Flows.
View full article
"switch by case" is a stucture in many programming languages. It is a availbale in Flexscript. A case must be a number for a switch by case structure in Flexscript. A decide activity can switch even to string value cases. All you need is to rename the connector from a decision activity to a following activity. process_flow_by_case.fsm
View full article
One of the most powerful commands in FlexSim is the query() command. It allows you to run SQL-like queries on virtually any data structure in the tree. If you don't know what that means, or what SQL is, or why it would be good to have SQL in FlexSim, this article is for you. If you have general ideas, but you would like to know more, then this article is for you. This article is not about connecting FlexSim to an external database. If that is your goal, then this article is not for you. Basics - Tables Data is often arranged in a table, which very loosely means that data is organized into rows and columns. However, SQL (and therefore the query() command) was designed to work only on certain kinds of tables, that look something like this: Name Age Fur Color Scooter 6 Brown Spot 3 Brown Whizby 4 Black Notice the following points about this table: Each column has a unique name There are no row headers (although if your table in FlexSim has data in the row header, that's okay; we'll get to that later) The table is a list of things, and each row in the table represents a single thing. The columns tell you the data that is stored about each thing. In this table, each thing is a pet, and each row stores the name, age, and hair color (the columns) of each pet. If our data included another pet, it would make another row in the table. In database lingo, a row in a table is called a record. One other thing you need to know about this table is that it has a name (in this case, "Pets"). All tables in SQL have a name, and follow the format described previously. Basics - Tables In FlexSim FlexSim has several different ways you can store data. Most users employ Global Tables and Lists (found in the toolbox) to manage data in their model. More advanced users sometimes create tables or bundles on labels. Then there's the model itself, which stores your object's locations in a tree data structure. All the data about where and object is, and how big it is, is stored in the model tree. So which of these data structures meet the standards for a SQL table? As far as the query() command is concerned, all of them do. The query() command is flexible enough to handle any data structure. The trick is to imagine your data as a table. To do this, you need to be able to answer the following questions: How many rows are there? What columns will the table have? How do you get the data for each cell? Phrased another way, given a row and a column, how do you put data in the table cell? If you can answer these questions, you can use the query() command. Let's apply these questions to two data structures in FlexSim: the Global Table, and the Global List. For the Global Table, the answers are very straightforward, but follow along to get the hang of it: Q: How many rows are there? A: The number of rows in the Global Table. Q: What columns with the table have? A: The same columns as in the Global Table. Q: How do you get the data for each cell? A: Given the row and column, look up the value in the Global Table For the Global List, things get a little more interesting: Q: How many rows are there? A: The number of entries on the list. Q: What columns with the table have? A: There is a value column, and there is a column for each field on the list. Q: How do you get the data for each cell? A: Remember that each row represents an entry on the list. For the value column, I get the value that was pushed on to the list to create the entry. For each field column, I get the value of the field for that entry. For example, suppose you have this list: Then supposed that you pushed a 5, 23, -12, 7, and 2 on to this list. When you view the entries on the list, you can see the data on this list laid out as a table: Notice that the value column has the values that were pushed on the list. The field columns (Doubled, Tripled, OddOrEven, and IsNegative) are each filled with the values of that field. The query() command has built-in support for Global Tables and Global Lists. However, it is always important to remember that to the query() command, the data is laid out in a table. If the data is not laid out in a table, you can still use the query() command, but you will need to use the methods explained in the Explicitly Defined Tables section. Basics - Queries SQL stands for Structured Query Language, so we can guess that it is a language for making queries. So what is a query? In a general sense, a query is a question. In SQL, a query is a question with two parts: who are you asking, and what do you want to know? There is a general answer to both parts of the question, and this is where tables come in. The answer to the first part (who are you asking?) is always a table. A SQL query is always directed at one (or more) tables. The answer to the second second part (what do you want to know?) is usually a new table. A SQL query takes in a table, and gives back a new table. The power in SQL comes from the new tables you can make. You can make a table that is a sorted version of the old table, like sorting data in excel. For example, if you have a list of items that need to be processed, you can sort that list by the item's priority. You can also make a table that is a filtered version of the old table, meaning you only kept certain rows. For example, if certain operators can only do certain tasks, you can make sure to only include the tasks that operator can do. In fact, you can make a table that is filtered, sorted, and modified in several other ways all with one query statement. Basics - Queries in FlexSim Let's look at examples of the query() command. You can follow along using the attached model ( numberlist.fsm). That model has a script that pushes values on to the list, and then queries the list. It also puts the result into the Global Table called QueryResult. Let's look at the line of that script with the query() command: int newTableRows = query("SELECT value FROM NumberList"); This line has a lot of new material. You can see that the query() command takes at least one argument, which is the text of a SQL query. We'll discuss the query itself in a moment. The query() command takes in the SQL query, and creates an internal (and invisible) temporary table that contains the result of the SQL query. It then returns the number of rows in the temporary table. Since you can't readily see the new table made by the query() command, you may want to copy the temporary table to a global table, using the dumpquery() command, as the script does: dumpquery(reftable("QueryResult"), 1); The temporary table lasts until you run the query() command again. Now for the query itself. You can see two parts of this query. The question "What do you want to know?" is answered by the SELECT statement. The question "Who are you asking?" is answered by the FROM clause. In this case, the FROM clause just lists one table, the NumberList. Recall that even though the NumberList isn't technically a table, you can visualize it's data as a table, which is what the query() command does (you can always right-click the NumberList in the Toolbox and choose the "View Entries" option to see the data as a table). In this example, the SELECT statement lists a column name. This means that the resulting table will have 1 column, because only one is required by the SELECT statement. When you run the script, it will put the result of the query in the QueryResult table: Notice that this table has only one column, the value column. If you look at the NumberList entries, you will see that this column is identical to the value column in that table. Examples To give you a general idea of what you can do with queries, these examples show a few common tasks. The examples all query the NumberList, which can be visualized as the following table: Selecting Multiple Columns SELECT value, IsNegative FROM NumberList Filtering SELECT value, IsNegative FROM NumberList WHERE IsNegative == 1 SELECT value, OddOrEven FROM NumberList WHERE value >= 5 Sorting SELECT value, Doubled FROM NumberList WHERE value >= 5 ORDER BY value Advanced - Callback Values It is often necessary to create a dynamic query. In FlexSim (not in regular SQL), you can do this by replacing a value in a query with a $n variable. This variable corresponds to additional parameters in the query() command. If you specify $1, then the value in the query will be the first additional parameter in the query() command, $2 will correspond to the second, and so on, up to $9. For example: query("SELECT Col1, Col2 FROM MyTable WHERE Col1 > $1 AND Col2 < $2", 10, 20) This query creates a table with Col1 and Col2, but only the rows where Col1 is greater than 10, and Col2 is less than 20. It is possible to include the values 10 and 20 in the query text. However, the $ variables allows you to easily change the value in the query, and replace them with more complicated expressions. Note that using callback values in a query where the FROM value is a Global List is not supported before versions 16.0.6/16.2.1. Advanced - Explicitly Defined Tables and the $iter() command Another FlexSim-specific feature of the query() command is the ability to explicitly define a table. This means you can query data that isn't arranged in the table format. In order to do so, you will need to answer the questions posed above, but shown again here: How many rows are there? What columns will the table have? How do you get the data for each cell? Once these questions are answered, the query() command can treat your data like a table. Each of the following subsections will answer these questions in detail. Defining the Number of Rows Let's start with a simple example: query("SELECT 1 FROM $1", 5) Notice that we are selecting from a number, not a Global Table or Global List. When the query() command sees a number instead of a table in the from statement, it assumes that you are querying a table with that number of rows. The statement above yields the following table (after a call to the dumpquery() command): This table has five rows, because $1 (the first additional parameter) evaluates to 5. All the rows have the value 1 because SELECT can handle expressions as well as column names (or expressions involving column names). Note that defining a table will only work if you use callback variables. A from statement like FROM 5 is not valid. To determine the number of rows in the table, use callback variables in the FROM statement. Defining the Columns To define the columns of your table, use the SELECT statement. Each expression in the SELECT statement will result in a column. When you are explicitly defining a table, you will often use callback variables as columns. This is where we can take advantage of the query() command. The query() command is very different from most other commands, because most commands only evaluate their parameters once. The query() command, however, can evaluate its parameters as many times as it needs to. Let's look at another example: query("SELECT $2 FROM $1", 5, normal(0, 1)) The result of this query is the following table: Notice that the second parameter, corresponding to $2, was re-evaluated as many times as the query needed it. Getting the Value in Each Cell Finally, we need a way to access the correct value for a given row and column. To do that, we need a way to know which row we are currently dealing with. This is where the $iter() command comes in. For example: query("SELECT $2 FROM $1", 5, $iter(1)) The $iter() command accepts an argument. That argument should match the value of the callback variable, e.g. if you used FROM $1, then the $iter() command should take a one as an argument. The $iter() command is linked to the query() command, so that its return value depends on which row is being evaluated. The above query results in the following table: Notice that $iter(1) returned the row number for each row. Now we can begin to query the tree, as if it were a table. Let's start with a simple example. Suppose you wanted a table of all the names of the first-level subnodes of the model tree. Let's start by answering the three questions: Q: How many rows are there? A: The number of first-level subnodes of the model Q: What columns with the table have? A: A column for the name of each of those subnodes Q: How do you get the data for each cell? A: Given the row number, get the name of that object Let's translate those answers into a query. First, we need to query something that isn't in table format already, so we know we need to use callback variables in the FROM statement: query("SELECT ... FROM $1", ..., ...) Next, we need a column for the names of all the subnodes, so we add one to the select statement: query("SELECT $2 FROM $1", ..., ...) Next, we need to answer the question of how many rows there are. Since this is the number of subnodes, you can write that as content(model()): query("SELECT $2 FROM $1", content(model()), ...) Finally, we need a way to get the name of each of the subnodes. We know that $iter(1) will give us the values from 1 to content(model()), so we can use those values in the rank() command, and we can pass the result of the rank() command to the getname() command: query("SELECT $2 FROM $1", content(model()), getname(rank(model(), $iter(1))) ) After dragging in a few random objects into the model, you can run that query. If you use the dumpquery() command, you can get a table like this: In the previous example, we used the value from $iter(1), and passed it in to rank(), and from rank() to getname(), all to get the name of the nth subnode of the model. Since querying a node in this way is fairly common, the query() command also allows you to specify a node as a table, rather than a number. In this case, $iter(1) will iterate over all the subnodes of $1, rather than the values 1 to $1. This makes our query much simpler: query("SELECT $2 FROM $1", model(), getname($iter(1))) Advanced - Flattening Data There is another option for what you can query in a FROM statement. If you use a callback variable (like $1) as your table, then you can use flattening syntax, shown in the following example: query("SELECT $3, $4 FROM $1x$2", 3, 2, $iter(1), $iter(2)) This query makes the following table: Notice that for every possible value of $1, there is a row for every possible value of $2. That is the purpose of the x (called the flattening operator); it ensures that there is a row for each permutation of all the callback variables involved. A query containing FROM $1x$2x$3x$4 would produce a table with enough rows for each unique combination of $iter(1), $iter(2), $iter(3), and $iter(4), and then execute the query on that table. The user manual contains an excellent example of when flattening syntax might be helpful, shown in the help manual in Miscellaneous Concepts > SQL Queries > Example.
View full article
A.Hello everyone, Some people we very impressed by FlexSim in a logistics fair and they asked me why are we using Plant Simulation in stead of FlexSim ? I've never heard about this software before, so I had a look on youtube. And to be honest I was impressed by the 3D view and how easy was constructing an automated storage in few seconds without code. I'd like to ask if anybody have used this software ? And what do you think about it ? Thank you very much.
View full article
Article space for Production Engineer Book including FlexSim Examples from Brasil Este material de apoio faz parte do Livro Administração de produção e operações, manufatura e serviços: uma abordagem estratégica, dos autores Henrique Correa e Carlos Correa, em sua 5º Edição. Para auxiliar o aprendizado, este livro conta com exemplos em vídeo e modelos de simulações de processos disponíveis em diversos capítulos. O acesso ao material é gratuito e pode ser acessado através dos links abaixo nas descrições de cada capítulo. Aqui você encontrará o conteúdo detalhado, referente aos arquivos dos modelos de simulação (*.fsm) e os links dos vídeos no YouTube. Dessa forma, o leitor poderá usufruir dos arquivos de simulação criados para facilitar e enriquecer o seu aprendizado. Capítulo 10 Projeto do Produto e Seleção de Processos (Bens e Serviços) Call Center download modelo clique para assistir o vídeo Restaurante download modelo clique para assistir o vídeo Clínica download modelo clique para assistir o vídeo Loja de conveniência download modelo clique para assistir o vídeo Segurança de um aeroporto download modelo clique para assistir o vídeo Terminal Rodoviário download modelo clique para assistir o vídeo Hospital clique para assistir o vídeo Estacionamento clique para assistir o vídeo Capítulo 13 Localização e Arranjo Físico de Unidades da Rede de Operações Layout Celular clique para assistir o vídeo Layout em Linha clique para assistir o vídeo Layout por Processos (em breve) Layout Posicional (em breve) Capítulo 14 Capacidade Produtiva e Filas em Unidades da Rede de Operações Teoria das Filas download modelo clique aqui para assistir o vídeo Capítulo 15 Teoria das Restrições em Redes de Operações TOC Princípios 1-9 download modelo princípio 1 download modelo princípio 2 download modelo princípio 3 download modelo princípios 4 e 5 download modelo princípio 6 download modelo princípio 7 download modelo princípio 8 download modelo princípio 9 clique para assistir o vídeo Sistema Drum-Buffer-Rope (Tambor-Pulmão-Corda) download modelo clique para assistir o vídeo Capítulo 17 Gestão de Estoques na Rede de Operações Simulação de Reposição Periódica / Contínua (em breve) Capítulo 19 Sequenciamento, Programação e Controle de Operações Sequenciamento de Produtos e Otimização download modelo clique para assistir o vídeo Job-Shop download modelo clique para assistir o vídeo Capítulo 20 Just in Time (JIT) e Operações Enxutas (Lean) Produção Puxada vs. Empurrada download modelo clique aqui para assistir o vídeo Cartão Kanban Assista o vídeo e veja na prática um exemplo de simulação do sistema kanban. download modelo clique aqui para assistir o vídeo Desperdícios do Sistema Toyota de Podução (Lean) download modelo clique aqui para assistir o vídeo Setup Assista o vídeo da simulação de um processo de troca de piso da quadra de uma arena multiuso, utilizada para partidas de hóquei e de basquete. clique aqui para assistir o vídeo Informações Adicionais Os modelos de simulações e os vídeos apresentados foram construídos com o Software FlexSim, plataforma digital, a qual possui uma versão gratuita, FlexSim Express, disponível para download através da URL https://www.flexsim.com/pt/ Vídeo passo a passo download e instalação do FlexSim Express Vídeo requisitos de sistema hardware para utilizar o FlexSim Express Contatos suporte@flexsimbrasil.com.br / @Rodrigo Lamas / @Michael Machado
View full article
Neste Tutorial iremos demonstrar como criar uma apresentação do seu modelo no FlexSim, utilizando a ferramenta Flypath (Presentation Builder). Com esta ferramenta você poderá criar sua apresentação de forma rápida fazendo um filme de seu modelo. Nela você poderá definir vistas e os tempos entre as transições destas vistas no modelo. Apresentação a qual você poderá gravar em um vídeo de alta definição no próprio FlexSim, utilizando outra ferramenta chamada Video Recorder. Vamos lá! Assista o vídeo em nosso canal do YouTube e acompanhe as informações explicativas abaixo. Presentation Builder Após construir seu modelo acesse o Flypath para definir como o seu modelo se movimentará durante a apresentação, clicando em: Tools / Visual / Flypath Na janela Presentation Builder você irá criar um novo Flypath1 clicando em Então é só você selecionar a vista em seu modelo e clicar em , no centro da janela para definir uma vista, dentro do Flypath1 então movimente o cursor de tempo e selecione uma segunda vista, clicando novamente em . Este será o tempo em que a apresentação levará para chegar até a segunda vista definida por você. Você pode criar vários flypaths cada um com seu próprio conjunto de flypoints. Quando executado, a visualização 3D voará sequencialmente ou mover-se-á para cada flypoint no flypath. Por padrão, flypaths não estão associados com velocidade de simulação. Não se preocupe, o Presentation Builder vai definir para você todo o movimento entre as 2 vistas. Após concluir sua apresentação é só clicar em retornar para a primeira vista e rodar o Flypath , então você verá a apresentação levando em conta as vistas e o tempo definido no seu modelo em 3D. O Presentation Builder tem seu próprio conjunto de botões Iniciar e Parar. No entanto, ao usar o gravador de vídeo, você pode especificar um seu flypaths para ser executado durante a gravação de seu arquivo. Você também pode usar os botões e para caminhar entre as vistas, flypoints, definidas. Video Recorder Após construir sua apresentação utilizando o Flypath vamos gravar esta apresentação em vídeo! Para isso acesse: Tools / Visual / Video Recorder Na janela Video Recorder você irá configurar o seu vídeo para poder iniciar a gravação! Primeiro clicando em você cria um novo arquivo File Path de vídeo para ser exportado para seu computador. Lembramos que este procedimento pode ser feito para um conjunto de videos. Na seleção Codec, você pode escolher qual o codec que será usado para a gravação do seu vídeo, o mais comum é gravarmos em MPEG-4, (*.mp4). Selecione na sequencia a quantidade de frames por segundo que o seu vídeo será gravado, selecione por exemplo 30 para a opção FPS. Na etapa seguinte, Size, você poderá definir a resolução e o tamanho do seu vídeo Neste exemplo iremos utilizar a opção "use basic sequence" na qual iremos definir o Flypath1 criado como referencia para a gravação do vídeo. Logo é só definirmos o tempo para o início e fim do vídeo e sua velocidade no modelo 3D. Lembre-se que o tempo do Flypath tem que estar dentro do tamanho do vídeo, caso contrário o Flypath irá se repetir. Exemplo: Para um Flypath de 20 segundos e uma velocidade de Speed 4, teremos que gravar um vídeo de 5 segundos. Lembre-se de utilizar a Amostra "Sample" para selecionar no seu modelo 3D a vista a qual o vídeo iniciará a gravação em View, utilize a primeira vista definida no seu Flypath. Após concluir as configurações clique em Record, no canto esquerdo da janela Video Recorder. Pronto! Seu vídeo será gravado e poderá ser acessado em: Segue o modelo referente ao artigo: modelo-flypath-videorecorder.fsm Inscreva-se e acompanhe nosso canal de videos no YouTube FlexSim Brasil
View full article
Cycle time per process.fsm When we create simulation models, sometimes we limit ourselves to modeling a process or a part number, in which we have problems. But what happens when we run a complete production plan with different part numbers, which in turn run at different cycle times? This is a way that allows you to run different part numbers in as many different processes as you want, each with its own cycle time. What do we need? 1.- Label on each item that identifies what part number it is. For example • Label: IDpart Value: ABC12 2.-Label on each machine that identifies the process that it runs. For example • Label: Station Value: Processor1 3.- Global table that contains in the columns the different processes that you have in your production line and in the rows the different part numbers that can run in your line. The information contained in this table will refer to the cycle times of each part number in each process. For example: Processor1 Processor2 Processor3 ABC12 20 10 13 BAC21 11 30 20 4.-You must configure the processing time of your processor referring to your global table and placing the following: With this, we will obtain weighted usage statistics for the equipment. Benefits: 1. You can run different part numbers on the same line with their respective cycle time each. 2. More accurate use of equipment and operators. 3. Modifying cycle times in a global table is easier and more controlled than directly in the processes. 4. Calculation of the capacity of your line running a real production plan will be accurate. 5. You can add and remove processes or even modify the flow of your line without affecting the cycle time that processor runs. Since it is referenced by its label to the global table.
View full article
Cycle time per process.fsm Cuando creamos modelos de simulación en ocasiones nos limitamos a modelar un proceso o un numero de parte, en el cual tenemos problemas. Pero ¿Qué pasa cuando corremos un plan de producción completo con distintos números de parte, que ha su vez corren a diferente tiempo ciclo? Este es una manera que permite correr diferentes números de parte en diferentes procesos tantos como tu desees, cada uno con su tiempo ciclo. ¿Qué necesitamos? 1.- Etiqueta en cada ítem que identifique que numero de parte es. Por ejemplo Label: IDpart Value: ABC12 2.-Etiqueta en cada máquina que identifique el proceso que este corre. Por ejemplo Label: Station Value: Processor1 3.- Tabla global que contenga en las columnas los diferentes procesos que tienes en tu línea de producción y en los renglones los diferentes números de parte que pueden correr en tu línea. La información que contenga esta tabla será referente a los tiempos de ciclo de cada numero de parte en cada proceso. Por ejemplo: Processor1 Processor2 Processor3 ABC12 20 10 13 BAC21 11 30 20 4.-Deberas configurar el tiempo de procesamiento de tu processor haciendo referencia a tu tabla global y colocando lo siguiente: Con esto, obtendremos estadísticos ponderados de utilización para los equipos. Beneficios: Puedes correr diferentes números de parte en una misma línea con su respectivo tiempo ciclo cada una. Utilización de equipos y operadores mas exacta. Modificar tiempos ciclos en una tabla global es más fácil y controlado que directo en los procesos. Cálculo de capacidad de tu línea más exacta corriendo un plan de producción real. Puedes agregar y quitar procesos o incluso modificar el flujo de tu línea sin afectar el tiempo de ciclo que corra ese procesador. Ya que esta referenciado por su etiqueta a la tabla global.
View full article
RailWorks 25.0.1 is now available (19 March 2025). This version of RailWorks is intended for use with FlexSim 2025. All versions can be found in the Downloads section of your FlexSim account on the 3rd party modules tab. Please do not hesitate to report any bugs, usability improvements and feature requests to developmentbrflexsim@flexsbr.com.br. Rail Network: New feature in RailWorks The Rail Network feature provides users with an intuitive and efficient way to design and connect railway systems. With a user-friendly interface, this tool enables seamless track placement, automatic node linking, and real-time validation to ensure smooth rail operations. Users can quickly define routes, junctions, and stations while leveraging smart snapping and alignment aids to simplify complex track layouts. This feature is designed for both beginners and advanced users, offering powerful tools to build scalable and efficient rail networks with minimal effort. New Speed Table: New feature in RailWorks Offering more speed possibilities to configurate all the movement parameters, the new speed table covers all movement speeds, acceleration and deceleration parameters, making the model more plausible and adherent to the real world process. About Railworks The FlexSim Brazil RailWorks module consists of premade custom objects, designed to represent a real environment for the Rail problem modeling, with less configuration. Our approach is to unite 3D modeling with the Process Flow functionality, allowing object configuration and visualization through the native 3D FlexSim solution, and the rail system events to be triggered by the Process Flow, using not only defaults FlexSim Process Flow activities, but also new ones developed by our team. Release Notes View the full release notes in the online documentation. RailWorks 25.0.1 (19 March 2025) Features Feature: Rail Network A new way to create and connect your rails into the model. Simple as network nodes, now you can connect the RailNetwork nodes and easily create your own rail tracks. Feature: New Speed table Offering more speed possibilities to configurate all the movement parameters, the new speed table covers all movement speeds, acceleration and deceleration parameters, making the model more plausible and adherent to the real world process. Bug-Fixes Fixed moveWagon auto decouple operation. Fixed a bug where SendToPortal was not freeing rails. RailWorks 24.2.7 (17 January 2025) Bug-Fixes Fixed moveWagon auto decouple operation. Fixed a bug where SendToPortal was not freeing rails. RailWorks 24.2.6 (17 October 2024) Bug-Fixes Improved couple and decouple internal operations. Improved offset calculations internal operations. Fixed a bug where all flowItem classes was the same in different stations. Fixed a bug with passenger locomotive. RailWorks 24.2.5 (25 September 2024) Bug-Fixes Fixed a bug on creating Station object.
View full article
Dear FlexSim user, Update: Please see the FlexSim Newsroom announcement here: FlexSim Answers to migrate to Autodesk Forums on April 25 | FlexSim Original First and foremost, thank you for being an active and valued member of our forum. Your contributions help make this community a valuable resource for everyone, and we truly appreciate your participation. As you may know, FlexSim was acquired by Autodesk in late 2023. As part of this transition, we will be migrating some of our tools, including this forum, to a new platform which we expect to be completed by May 2025. You will be able to access Autodesk forums here. What This Means for You: Seamless Knowledge Transfer – All existing forum content will be migrated, ensuring continued access to the wealth of knowledge shared by our community. A Community-Driven Experience – The forum will evolve into a more self-sustaining, peer-to-peer support hub. While FlexSim support engineers will still visit the forum, when possible, our goal is to empower users to help each other, making this a truly community-led space. Ongoing Support for Entitled Users – We will share more details soon on how eligible users can reach the FlexSim support team directly. For now, we encourage you to continue engaging with the forum as you always have. Your involvement is what makes this community thrive, and we’re excited to embark on this new chapter together. Stay tuned for more updates and thank you for being an essential part of FlexSim! Best, The FlexSim Team
View full article
Intersection with traffic lights in an AGV network This model aims to showcase how allocations of control areas can be manually controlled to achieve more complex logic than the default “first come first serve” implementation. It depicts a four-way road intersection with arriving cars being able to continue in any of the three other directions. Cars driving straight on or turning right use the right lane, cars turning left use the left lane and must give way to oncoming traffic. Traffic lights manage which cars are allowed to enter the intersection at any given time. AGV network and general concept In order to understand the logic behind it, let’s first look at how the AGV network is setup. In the screenshot below we deactivated the visualization of the roads to show the paths and areas more clearly. For each of the four directions there are two incoming paths and one outgoing path. Control points (red) are placed on the incoming paths at the points where cars must stop (based on object center) when the light is red. A single, large control area that control the entry is placed such that is encompasses the entire intersection. Within this control area, an additional control point is placed on each of the left turning paths (orange). This is the location where left turning vehicles must wait for the oncoming lane to be clear. To enforce this the four smaller, rectangular control areas are used. The lane turning left and both the straight and right turning lane coming from the other direction pass through one of these areas. We will later explain how the straight and right turning cars are given priority to allocate these areas, resulting in cars wanting to turn left having to wait until no other allocation requests are present. As all paths are one-way and the geometry is pretty simple, all things considered, the distance between cars is handled by an accumulation behaviour set on the paths. The logic controlling the vehicles is very simple. If we zoom out, we can see that cars leaving the intersection in any direction eventually just turn around and return. At the turning points control points are placed that serve as the travel destination for the cars. A Process Flow with one token per car randomly chooses the next destination when the previous travel task is finished and sends the car there. The cars will automatically use the correct lanes, since those are the shortest paths to reach their destination. For the intersection logic each combination of origin and destination (meaning every possible way of crossing the intersection) is represented as a number. These numbers are stored as global macros for ease of use. The letters represent the four cardinal directions (north, west, south, east). For example, using the intersection to travel from east to west would be represented by the ‘mode’ number 4. At the same time as a new destination is chosen for the car, the respective mode number is also written to a label on the car. In the logic that controls entries into the intersection, these modes are used to identify which vehicles are allowed to enter. Powers of two are used, so the numbers can simply be added together to get a single number that encodes which lights are green. The light phases are defined in a global table. One of the simplest sensible configurations is shown below. At first, all lights are red (no entries in the “Green” columns) for 5 seconds. Then all cars coming from the west and east directions receive a green light for 20 seconds. This is followed by another 5s of all red lights and finally the other directions are allowed to move on. The table is then repeated from the top. The phase in line two would be represented as mode 1365 (1 + 4 + 16 + 64 + 256 + 1024). This becomes a lot more obvious when the mode is written in binary: 0000 0101 0101 0101 Each bit represents one of the possible directions. Allocation logic explained The control area is set to allow 0 concurrent allocations. Meaning for a request to actually result in an allocation, we need to override the return value of the “On Request” event of the control area. This happens in the control logic for the intersection that is implemented as an Object Process Flow linked to the control area. An Event-Triggered Source reacts to the On Request event and writes a reference to the “Allocator” (meaning the car/AGV) to a label on the token. Note that the “Will Override Return Value” box is checked. The token then enters a Finish activity in whose “Return Value” field the current traffic mode of the control area is compared to the mode of the requesting car. The “&” is the bitwise-and-operator. It goes through both numbers bit by bit. If the bit at a given position is 1 in both numbers, it will also be 1 in the returned value, 0 otherwise. If the mode of the car is part of the current traffic mode (which is a sum of such modes) the result will be the mode. This non-zero number is interpreted as “true” in the if-condition and the return value of the code is to allow the request to go through. Otherwise, the request is blocked. (The “Allow” and “Block” properties return 1 and -1, respectively.) The second part of the Process Flow is a loop with a single token that reads the next traffic mode from the global table. It then ‘announces’ which phase the intersection will enter next, so that the draw logic of the traffic light objects can start the process of switching from red to green or vice versa if needed. After a delay, in which those lights would show yellow, the current phase of the control area is updated. The same code that updates the label then also searches for cars that are now allowed to enter the intersection among the pending allocation requests. Since, as far as I could tell, there is currently no direct method to refire an allocation request, those cars receive a pre-empting task sequence that uses a break task to immediately return to the previously active sequence. The restart of their travel task then causes them to try to allocate the control area again. After waiting the duration assigned to the current traffic phase, the token once more updates the mode of the intersection to an ‘intermediate’ mode. This mode is the result of another bit-wise comparison of the current and the next mode. This allows lights that need to change to red to do so, while lights that stay green remain unchanged. Once the next phase is activated, additional lights might then become green. If the next phase doesn’t have any green lights, all lights will already be red in the intermediate mode, meaning the Process Flow block that updates the mode can be skipped and the token instead just waits out the duration in the “All Red Duration” Delay activity. The logic that makes left turning vehicles give way to oncoming traffic works in a similar way. It is also implemented as an Object Process Flow, linked to the four smaller control areas within the intersection. These areas allow a single allocation by default and also have a “Mode” label. But it’s not set based on a timer and otherwise static. Instead, these areas start in mode 0 and if a request is made while the area is empty, the allocation is always allowed, and the mode is set to match that of the allocator. When another request is made, the areas mode is compared with that of the new requesting car. If they match, the request can potentially be granted. First however, the code searches other pending requests for a mode with a higher priority than that of the current request. (The mode numbers are assigned in the order straight < right turn < left turn, so they can also be used as a priority value, where lower is better.) If such a request is found, the current one is blocked, to allow for the area to empty. At that point, a token created by a source listening to the “On Deallocated” event of the control area will reset the mode of the area to 0 and sort any pending requests by priority, before those get re-evaluated. In summary, this logic allows an arbitrary number of cars with the same mode to enter the area. As soon as a higher priority request that can’t immediately enter is created, other requests are blocked; they must ‘give way’. Visualization and parameters The traffic lights are BasicFR objects that draw colored circles as lights in their On Draw trigger, depending on a label. That label is updated in the On Message trigger whenever the intersection changes its phase. The roads are drawn along the AGV paths in the On Draw code of a dummy object placed to the side of the intersection. How wide and in what interval the white lines are drawn is determined by Array labels on the paths containing all necessary parameters. The model comes with five parameters: The first controls which table is used to determine the traffic light phases, the second and third set the time it takes a light to switch from red to green and green to red. The fourth sets the number of cars and the final one switches the visualization of the left turn lights to arrows. agv-traffic-mode-intersection.fsm
View full article
Staying up-to-date FlexSim recommends staying up-to-date and using the latest Software version. New features, improvements, and bug fixes make your simulations more stable, more powerful, and easier to build.   In addition, the Software is developed for use with contemporaneous hardware, operating systems, and drivers. Among other reasons, as third parties phase out these technologies, FlexSim must discontinue support for Software versions developed for use with those technologies.   Finally, as usage of older versions decreases, FlexSim must devote its resources to supporting more recent Software versions to best serve the majority of our customers who stay current on Software maintenance and updates.   Lifecycle and Support Policy If you must use an older Software version, understanding the Software Support Lifecycle will help you make informed decisions about when to upgrade.   A Software release is generally supported until it is four (4) or more versions prior to the current release. For the most up-to-date lifecycle and support policy information, please see section 17. Software Support of FlexSim's Software License Agreement.   Lifecycle status terminology Supported - FlexSim will maintain licensing infrastructure necessary for a given Software version and will provide technical support for that version for licensed users under current maintenance or subscription. Bugfixes - Bugfixes are issued periodically for the latest Software version, as needed. A Software version typically receives bugfixes until the next Software feature release. Learn more about FlexSim version numbering and bugfixes. LTS - Long-term support versions receive bugfixes for a longer period, typically 12-15 months. Beta - Preview the next version of FlexSim Software for demonstration, testing, and validation. Beta versions may not be suitable for day-to-day production use. Beta versions are superseded by their production-release version. No support - After a Software version is 4 or more versions older than the latest release it is no longer supported. Such a version may continue to work on the computer where it is installed and licensed, but it is no longer eligible for technical support and FlexSim cannot guarantee that licensing infrastructure will remain in place to move the license key to another computer. Supported Versions The following Software versions are currently supported.    Application   Version   General Availability     Lifecycle Status  FlexSim 25.1 2025-04-14   supported + bugfixes FlexSim 25.0 2024-12-11   supported + LTS FlexSim 24.2 2024-08-05   supported FlexSim 24.1 2024-04-08   supported   Unsupported Versions The following Software versions are past their supported lifecycle. We recommend updating your software to a supported version.    Application   Version   General Availability   End-of-Life   Lifecycle Status  FlexSim 24.0 2024-12-06 2025-04-14 no support FlexSim 23.2 2023-08-07 2024-12-11 no support FlexSim 23.1 2023-04-03 2024-08-05 no support FlexSim 23.0 2022-12-05 2024-04-08 no support FlexSim 22.2 2022-08-02 2024-04-05 no support FlexSim 22.1 2022-04-04 2024-04-05 no support FlexSim 22.0 2021-12-06 2024-04-05 no support FlexSim 21.2 2021-08-09 2024-04-05 no support FlexSim 21.1 2021-04-02 2024-04-02 no support FlexSim 21.0 2020-12-04 2024-03-26 no support FlexSim 20.2 2020-08-11 2024-03-26 no support FlexSim 20.1 2020-04-10 2024-03-26 no support FlexSim 20.0 2019-12-06 2023-12-31 no support FlexSim 17.0 - 19.2 various 2023-12-31 no support FlexSim 7.7 - 16.2 various 2022-06-30 no support HC 5.3 2017-10-13 2022-06-30 no support FlexSim < 7.7 various 2020-12-31 no support HC < 5.3 various 2020-12-31 no support   Notes The date format used is YYYY-MM-DD Bugfix releases follow the same lifecycle as the major release with which they are associated. Versions not listed should be assumed as past their supported lifecycle.
View full article
Playing Multiplayer Tag in FlexSim! TagServer.fsm TagClient.fsm This is a side project to show off some fun things FlexSim can do using sockets. Sockets are just one possible way that one instance of FlexSim can communicate with another. In its simplest sense, a socket is just a port number and an IP address that computers use to send information to each other. For example, whenever a computer visits a website, it uses sockets to create a connection to the webserver's IP address on port 80 (HTTP) or port 443 (HTTPS). All of this occurs within the framework of the TCP/IP network. Similarly, FlexSim can establish socket connections to communicate with another FlexSim as long as you know the IP address and choose a port for both instances to connect on. Establish Socket Connection In this game of tag, the model that acts as the server uses these commands to set up socket connection with the client: socketinit(); servercreatemain(8002); serveraccept(0); Note: All of the commands in this article can be found in the documentation The client then runs the following to connect to the server. The HostIP should be the IP address of the device running the server model (or 127.0.0.1 if running both client and server on the same machine). socketinit(); int a = clientcreate(); int a_con = clientconnect(a, HostIP, 8002); On both the client model and server model, these commands are in the OnRunStart trigger and the server creates 5 socket connections for each player. 4 for inputs (up, down, left, right) and 1 for passing in their player name from the client. The server model will freeze and wait for all sockets to be set up. For example, if there are 3 players, the server model will wait until 3 clients have successfully ran the client model and connected. After all clients have connected to the server, we can use clientsend() and serverreceive() to send information from client to server. An example of this is sending movement inputs from client to server. This is what that looks like: Client // MOVE if (iskeydown(87)){ clientsend(2, "up"); } if (iskeydown(83)){ clientsend(3, "down"); } if (iskeydown(65)){ clientsend(4, "left"); } if (iskeydown(68)){ clientsend(5, "right"); } Server string up1 = serverreceive(token.Rank * 5 - 3, NULL, 100, 1); string down1 = serverreceive(token.Rank * 5 - 2, NULL, 100, 1); string left1 = serverreceive(token.Rank * 5 - 1, NULL, 100, 1); string right1 = serverreceive(token.Rank * 5, NULL, 100, 1); // token.Rank is the number of the player (1,2,3 etc.) and is used to reference the right // socket for each player's inputs //reset coordinates te.X = 0; te.Y = 0; te.Stop = 0; if (up1 != ""){ // up W meaning the server received an input on this socket te.Y = 1; // this accounts for getting multiple messages from client like "upupup" } if (down1 != ""){ // down S te.Y = -1; // this label is later used in a travel activity } if (left1 != ""){ // left A te.X = -1; } if (right1 != ""){ // right D te.X = 1; } Note: In a typical game environment, the server is also sending information back to the clients, but in this example, all visuals and logic occur on the server. Game Logic All game logic is found on the server process flow. Setup and Order of Models To play Tag, follow these steps: Note: If there are certain firewalls or security groups on your network that doesn't allow traffic into FlexSim outside local networks you may be limited on who can connect to play tag 1. Open TagServer model and change NumPlayers parameter to the desired number of players 2. Open TagClient model and change both global variables (HostIP and EnterNameHere). Again, if everything is running on the same device, use 127.0.0.1 as the HostIP global variable value. 3. Reset and Run the TagServer model first 4. Reset and Run the TagClient model. You should get this output if connection was successful 5. Run clients one at a time for each player until all players have connected and the server will run automatically. This is the output on the server upon successful connection 6. Enjoy!
View full article
This model, developed by @Jacob W2, demonstrates a method of using a kinetic tracked variable to measure process completion on a processor. This allows a processor to have a dynamic processing time, which isn’t possible using the standard processor logic. This is all handled though the use of an object process flow that easily allows other processors to be used in a similar fashion. Kinetic tracked variable.fsm This is the basic layout for the model: a source, a basic fixed resource, and a queue. A basic fixed resource is used in lieu of a processor because it has no innate logic that needs to be dealt with. This is the object flow layout. It’s fairly simple, but handles all of the logic we will need for the processor to work. The “Model Start Logic” container allows the first item to enter the processor. The “Item Control” section is the main feature of the model. A token is created whenever an item enters the processor. A process time label is created on the token, which sets when the process will be completed. This value should be set in model time units. For example, if a part takes one minute to complete and the model time is in units of seconds, the value should be 60. The Initialize Tracked Variable custom code activity is what actually creates the tracked variable that represents the processing progress. First, a treenode has to be created for the label, and then the tracked variable needs to be initialized with the correct type; in this case, a kinetic level tracked variable. A token is then created in the Variable Rate Loop. This token is used to set the processing rate. First, the token will set an initial rate for the tracked variable, and then after a random delay, it will set a new rate for the part processing. It continues to loop until released by its parent token. While the token for tracking the rate is looping, the token in the “Item Control” container is at the Wait for Event activity watching the tracked variable that we created. Once the tracked variable reaches the value of the process time label, the token releases the item from the processor, and then readies the processor for the next item through a custom code activity. The tracking rate token is then released to a delay and sink activity block, and the original token is then sent to a sink activity. When another item arrives, a new token is created in the “Item Control” container, and the process outlined above is repeated. This application of kinetic tracked variables can be extended to a more complex model that has varying process times based on the availability of operators. More specifically, this model allows operators to be added to the process dynamically when they are available, and the number of operators working on the process directly affects the processing time. KTV_Operators.fsm This model layout contains two sources, two basic fixed resources, and two queues in parallel. It also contains five operators, which are grouped according to their shift. A kinetic tracked variable is once again used to represent the processing time or completion rate of an item, and the rate changes dynamically based on the number of operators working on the job at a time. The logic is contained in an object process flow, which is attached to the two basic fixed resources. The first of the three main containers, “Create Tracked Variable and Wait,” creates the tracked variable for the processing time and waits for processing to be complete. The second container acquires the operators from a list based on the current shift. The last container controls operator movement and changes the processing rate. This logic allows operators to come and go during shifts. The rate can be changed dynamically. As illustrated with the above examples, kinetic tracked variables are a powerful and versatile tool, allowing a greater level of control and customization over your model.
View full article
Changing the packing method for task executers can be tricky and also can vary widely between types. In this article we'll explore the default packing method for each TE and how to alter it to suit the model's needs. Attached is a model which demonstrates the default packing method and the comparison. The model is also the best place to get premade code for the ASRS, the crane, and the Robot: TEStackingNew.fsm Default Stacking on Task Executers There are two types of default stacking methods on the TE's. AGV's, operators, forklifts, ASRS, and basicTE's all use a simple up and down stacking method: The other TE's (elevator, robot, and crane) don't separate the boxes at all so they all look like they're on top of each other (this is because they're mostly meant to only carry one item at a time): Changing the Stacking Pattern: AGV, Operator, & BasicTE: For these objects, changing the stacking method is relatively simple. Add 5 labels to the object: numx, numy, xshift, yshift, and zshift Add an OnLoad trigger in the properties panel Set the trigger by going to Visual->Set Location Type in this code current.xshift+item.size.x*((item.rank-1)%current.numx) -current.yshift+item.size.y*(Math.floor(((item.rank-1)/current.numx)%current.numy) - (current.numy-1)/2) current.zshift+item.size.z*Math.floor((item.rank-1)/current.numx/current.numy) The only thing that differs between these 3 objects are the label values. The labels "numx" and "numy" sets the number of objects in the x direction and how many in the y direction. For example a 3x3 grid on the AGV would set "numx" be 3 and "numy" be 3 xshift yshift zshift AGV 1 .5 .5 Operator .75 .29 1.10 BasicTE 0 0 .85 Elevator, Robot, & Crane: These objects are very similar to the TE's above. You'll follow the same steps above, except on the On Load trigger, choose to just paste custom code in the box. They have slightly different code (due to the different direction/ways of stacking) that you can copy from the model above. However, you will still add the labels to the TE's. You can set them using labels like these: xshift yshift zshift Elevator .7 1 .095 Robot .34 .35 .2 Crane .2 .5 -.25 Forklift: This is the easiest object to change because it is already built into the TE. To change the stacking pattern just add an OnEntry trigger and select Transporter Stacking Method, then just change the values to be what you would like. ASRS: For this one, you can change the stacking method by editing the model tree. The steps to change it are simple but specific: Open the model tree for the object by right clicking and selecting Explore Tree Find the behaviour node beneath the ASRS Node Add an node underneath called "eventfunctions" Beneath the node you just created add a node called "OnPreDraw" Paste in that node the code below (you can edit this to alter the stacking method how you would like): inheritcode(); TaskExecuter current = c; Object followingObj = first(current); double numx = 1; double numy = 4; double xshift = .95; double yshift = 1.45; double zshift = .1; while(objectexists(followingObj)){ double x = xshift+followingObj.size.x*((followingObj.rank-1)%numx); double y = -yshift+yloc(node(">visual/drawsurrogate/Lift/Slide", current))+followingObj.size.y*(Math.floor(((followingObj.rank-1)/numx)%numy) - (numy-1)/2); double z = zshift+followingObj.size.z*Math.floor((followingObj.rank-1)/numx/numy); double xFactor = 0.5; double yFactor = 0.5; double zFactor = 0; setloc(followingObj, x, y, z, xFactor, yFactor, zFactor); followingObj = next(followingObj); } Some things to keep in mind: Each TE is completely customizable by the user so the offset I considered to look right may not look right to you, the good thing is it's very changeable!
View full article
Introducing FlexSim Galaga! GALAGA.fsm This is an example of how a game could be made in FlexSim. Feel free to download the model and try it out (FlexSim Version is 23.1). Or if you are interested, see below for how the game works. How it works FlexSim Galaga uses Process Flow to perform all logic that occurs in the game. It also takes advantage of Global Variables to keep track of game data as the game is played. This allows one token to set a variable, for example WaveCounter, and that same value can be referenced anywhere in the model. Player Movement and Inputs I used the function iskeydown() for all player inputs. A token loops through a Custom Code activity that continuously checks for which keys are being pressed and makes the corresponding changes in the model. An example of this for player movement looks like this: if (iskeydown(65) && te.location.x > -90){ // left A te.location.x = te.location.x - 10; } if (iskeydown(68) && te.location.x < 90){ // right D te.location.x = te.location.x + 1 For shooting, similar code is written and assigns a label to the player. This label is used for the token to act differently depending on what the player has bought from the shop. The shop inputs are similar and check if the player has enough money for the selected item in the shop. (See the process flow activities 'Shoot Inputs' and 'Shop Inputs' for how this is done.) Wave Health and Speed As the game plays out, waves get more difficult and arrive faster. Each enemy ship has a certain health value and money value that the player earns when destroying it. These values come from the Global Table WaveHealth. After 50 waves, this table is repeated to spawn new waves. This can go on forever in Endless Mode or this table can be modified during the Model run by buying Extreme Mode. The game starts with Waves that last 20 seconds. To make the waves arrive faster over time, this code lowers the WaveDuration from 20 to 15 to 10 etc. every 12 waves. 5 seconds is the fastest wave time and doesn't get any faster. if (WaveCounter % 12 == 0){ if (WaveDuration > 5){ WaveDuration = WaveDuration - 5; } } Enemy Ships and "Collision" Logic When enemy ships are created, they are added to a Global Map called ColShipMap. The key is the column number the ship is in (1-20) and the value is an array of all ships in that column. This makes it easy to check if a shot has hit a ship. While shots are moving the token they are associated with constantly checks the distance between the shot and any ships in that column (thanks to ColShipMap). The column the shot belongs to is calculated based on the x location of where it is created. When the distance between the shot and a ship in that column is close enough, labels are changed on the token so the game knows which ship was hit and to decrease the health or destroy the object entirely. double x = token.shot.getLocation(1, 0, 0).x; // inverse of token.item.location.x = ((index - 1) * 10) - 95; int index = (x + 95) / 10 + 2; token.Index = index; Array spaceships = ColShipMap[index]; Vec3 shotPos = token.shot.as(Object).getLocation(0.5, 0.5, 0); for (int i = 1; i <= spaceships.length; i++){ double spaceshipY = spaceships.location.y; if (Math.fabs(spaceshipY - newY) < 2) { token.Hit = 1; token.target = spaceships; token.SpliceIndex = i; break; } } Display There are several Billboard objects in the model that toggle depending on the state of the game. (switch_hideshape() is used to make them appear like they are flashing) Feel free to look in the process flow for when these occur, but the overall purpose is to inform the player of what is happening in the game. Note: If you zoom out and want to re-center the model for an optimal display. Open properties and click on the view called 'Menu.' Then close the properties window. All other windows like the Toolbox are closed to make game visuals better. Feel free to look into the Process Flow or Model Triggers for anything I didn't mention. Enjoy!
View full article
O link que segue leva a um vídeo no qual é apresentada uma Visão Geral sobre a ferramenta Script do FlexSim. Os tópicos abordados no vídeo são: O que é o Script? Componentes do Script? Como utilizar o Script? Quais as funcionalidades do Script. Vídeo Tutorial: Script Overview Esperamos que aproveitem mais este vídeo tutorial.
View full article
O link abaixo, remete a um vídeo onde mostramos como usar o recurso paths para criar o percurso que recursos e pacientes devem seguir durante o fluxo dentro de um hospital, respeitando os limites dos layouts feito em Autocad e, o impacto nos indicadores usando o dashboard para análise. Vídeo Tutorial: FlexSim Healthcare - Parte II Esperamos que aproveitem esses vídeos com algumas dicas simples.
View full article
Top Contributors