FlexSim Knowledge Base
Announcements, articles, and guides to help you take your simulations to the next level.
Sort by:
FlexSim 2018 Update 1 is available. 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. Release Notes Added a Database Connector tool and Database FlexScript API. Updated the Emulation module and added it to the toolbox. Updated object triggers to be dynamically added and executed to improve performance and flexibility. Added an option to store StatisticsCollector bundle data on the hard drive. Added a global preference for date and time formats, which will default to the system's locale settings. Updated the stick() command to be able to get information about the VR headset by passing -1 for the stick number. Added a Box Plot chart type. Added a visual Walls object, which can be connected to A* as a member. Added an option to reverse rows on a gantt chart. Updated how the gantt chart handles colors. Added a time window option to several charts. Improved axis title options on several charts. Added a y-axis range option to the time plot. Output, system, and compiler consoles now wrap lines. Added a binoculars button to the bottom of properties windows. Fixed a bug with using local variable "a" within FlexScript lambda commands, such as findmatch(). Backwards Compatibility Note: the following changes may slightly change the way updated models behave. Removed FlowNode, Reservoir, WatchList, and other unused library class objects. Changed transportincomplete() to be more fail-safe so that it only affects the object when called correctly. Fixed an issue with the Rack sometimes receiving items out of order when the upstream object is using a transport. Process Flow Added a Variable shared asset. Updated the Event-Triggered Source and Wait for Event activities to be able to match values. People Added a Waiting Line object and a Wait in Line activity. AGV Fixed a bug with preempting an AGV during a pre-arrival event. Backwards Compatibility Note: the following changes may slightly change the way updated models behave. Improved AGV proximity detection for stop-space-based accumulation. Fixed an issue with reversing direction on accumulating paths. A* Added a routing mode for traveling at right angles only. Added an option for stopping and turning when changing directions. Added an option for routing by travel time. Improved the usability of creating and editing barriers and dividers. Added an option for snapping dividers between grid points. Fixed some visual issues with various components. Fixed a bug with distancetotravel(). Backwards Compatibility Note: the following changes may slightly change the way updated models behave. Improved the accuracy of the calculation of which grid points are affected by dividers. The mechanism for recovering from deadlock has been changed. The path costing system was slightly changed to allow for travel-time-based routing.
View full article
So you were trying to record a video and the Video Recorder crashed. Here is a step by step guide on how to debug the video recorder: Step 1: Is there a stop time in your model? In some older versions of FlexSim (2022 and older), if there is a stop time in your model that occurs during the model recording time, the video recorder will stop indefinitely at that time. Try removing any stop times that occur during the recording. Step 2: Are your graphics drivers up to date? (!!!!!!!!) This is the most common problem we see as to why the video recorder is not working. To start debugging this issue, check what graphics card FlexSim is using. If you open a model then go to Help->About FlexSim from the top toolbar, you will open this screen: The highlighted text that starts with OpenGL tell you what graphics card FlexSim is using. Now you might need to do a little research to find what graphic driver that card is using and then update it, but we've found in most cases updating the graphics card driver fixes video recorder issues. There's an article here the explains more on how to update your graphics driver (it's a very helpful read that also deals with some special cases on certain graphics cards). Make sure you're downloading either directly from the makers website or for your specific computer type, your computer will not be able to tell you if they're out of date. Step 3: Can you record a simpler video? If you make a very simple model (Source -> Queue -> Processor -> Sink), can you record it without issue? If you can then at least you know your video recorder can work, it is just having a issue with running a bigger model. If this is the case you might be running out of VRAM or the bigger model is taking so long to run that an outside manager is forcing it to close. If that is the case, here are some things to try: Update your graphics drivers (this is always the biggest issue). Revert your graphics card settings back to their defaults (for example, in the Nvidia Control Panel). For the next two suggestions go to the toolbar and click File -> Global Preferences -> Graphics Turn off Shadows and/or record a smaller resolution video to see if that helps. If it does, then the issue is likely that FlexSim is trying to use more VRAM than your graphics card supports. Make sure you are using the Recommended OpenGL Context and not the Generic (No GPU acceleration) or Core Profile contexts Step 4: Did your model crash previously while recording a video? There may be some corrupted data stuck in your recorder. It's an easy fix, you just need to delete your video recorder from toolbox and then re-add it: Step 5: Are you using a much older version of FlexSim? In a few of the older versions (2019.1 and older), temporary nodes from previous recordings caused the Video Recorder object to crash. To fix it all you need to do is clear the nodes Open your model, execute the following script, and then re-save your model: Model.find("Tools/VideoRecorder>variables/active").subnodes.clear(); Step 6: None of the previous steps worked, what now? If none of the above steps worked you can create and check debug log files, check the filepath, check various computer settings, and see the VRAM allocations to start solving the problem. Check the filepath FlexSim is putting the video from the video recorder into, if it is trying to put it in a strange place that can cause issues. FlexSim uses ffmeg to encode the captured frames into a video file, which leaves an ffmpeg_log.txt file in the directory where the video was created. That file might have something in it that might explain what is happening. You can create fslogfile.txt and exfslogfile.txt files in your FlexSim 20XX Projects directory that FlexSim can write debugging information into. Sometimes you might be able to get exception information in those files in certain cases: Check your settings in Windows or Group Policy or other IT software. It's possible something on your machine separate from FlexSim is noticing that the FlexSim process is taking a long time to respond and then killing its process because it thinks it is hanging. Try clicking the Record button and then not clicking any more anywhere on your machine until the recording is done. Or try recording a shorter timeframe to see if that helps. In Windows' Task Manager, you can add the Dedicated GPU memory column on the Details tab to see how much VRAM FlexSim is using. If FlexSim tries to use more memory than your graphics card supports (or if the total usage of FlexSim and all the other programs currently running exceed your hardware's limit), then FlexSim will likely crash the next time it tries to allocate and use any graphics objects stored in GPU VRAM (such as output buffers used by the Video Recorder, textures, 3D meshes, etc.). You can use Window's "dxdiag" tool to see how much VRAM your graphics card has: If you tried all of these suggestions and nothing worked, feel free to ask a question on the Q&A board and we can work to see if we can find a different solution for you!
View full article
At the current release state 2024.2.2 FlexSim does not provide a tool to export an animated USD stage of a model. There is a way around though by recording the FlexSim model connected to a NVidia Omniverse live session using one of the tools in NVidia’s USD Composer, the Animation Stage Recorder. This is a step-by-step tutorial to guide you through the process. It is assumed, when you are interested in this you already know how to connect FlexSim to a live session in NVidia Omniverse. This may not be ther perfect way to go, but it worked for me. Record_Animated_Stage_from_FlexSim.pdf
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
FlexSim 2018 includes functionality for creating a custom table view GUI using a custom data source from within FlexSim. This article will go through the specifics of how to set this up. The Callbacks Custom Table Data Source defines callbacks for how many rows and columns a table should display, what text to display in each of the cells, if they're read only etc. If you require further control of your table you can use a DLL or module and sub class the table view data source in C++. An example of how this data source is used can be seen in the Date Time Source activity properties. In the above table, the data being used to display both of these tables is exactly the same. The raw treenode table data can be seen on the right. The table on the left is displaying the hours and minutes for each start and end time rather than the the start time and duration in seconds. In FlexSim 2018, there are a number of tables that currently utilize this new data source. They can be found at: VIEW:/modules/ProcessFlow/windows/DateTimeArrivals/Table/Table VIEW:/pages/statistics/ChartTemplateProperties/tabcontrol>variables/tabs/StatePieOptions/SplitterPane/States/Table VIEW:/pages/statistics/ChartTemplateProperties/tabcontrol>variables/tabs/CompositeStatePieOptions/SplitterPane/States/Table VIEW:/pages/statistics/ChartTemplateProperties/tabcontrol>variables/tabs/StateBarOptions/SplitterPane/States/Table Copying one of these tables can be a good starting point for defining your own table. The first thing you have to do in order for FlexSim to recognize that your table is using a custom data source is to add a subnode to the style attribute of your table GUI. The node's name must be FS_CUSTOM_TABLE_VIEW_DATA_SOURCE with a string value of Callbacks. Set your viewfocus attribute to be the path to your data. This may just be a variable within your table. It's up to you to define what data will be displayed. If you want to have the default functionality of the Global Table View, you can use the guifocusclass attribute to reference the TableView class. This gives you features like right click menus, support for cells with pointer data (displays sampler), tracked variables (displays edit button) and FlexScript nodes (displays code edit button). If you're going to use this guiclass, be sure to reference the How To node (located directly above the TableView class in the tree) for which eventfunctions and variables you can or should define. At this point you're ready to add event functions to your table. There are only two required event functions. The others are optional and allow you to override the default functionality of the table view. If you choose not to implement the optional callback functions, the table view will perform its default behavior (whether that's displaying the cell's text value, setting a cell's value, etc). These event function nodes must be toggled as FlexScript. The following event functions are required: ---getNumRows--- This function must return the number of rows to display in the table. 0 is a valid return value. param(1) - View focus node ---getNumCols--- This function must return the number of columns to display in the table. 0 is a valid return value. param(1) - View focus node The following event functions are optional: ---shouldDrawRowHeaders--- If this returns 1, then the row headers will be drawn. The header row uses column 0 in the callback functions. param(1) - View focus node ---shouldDrawColHeaders--- If this returns 1, then the column headers will be drawn. The header column uses row 0 in the callback functions. param(1) - View focus node ---shouldGetCellNode--- Allows you to decide whether you want to override the table view's default functionality of getting the cell node. param(1) - The row number of the displayed table param(2) - The column number of the displayed table If shouldGetCellNode returns 1 then the following function will be called: ---getCellNode--- Return the node associated with the row and column of the table. param(1) - The row number of the displayed table param(2) - The column number of the displayed table ---shouldSetCellValue--- Allows you to decide whether you want to override the table view's default functionality of setting a cell's value. param(1) - The cell node as defined by getCellNode param(2) - The row number of the displayed table param(3) - The column number of the displayed table If shouldSetCellValue returns 1 then the following function will be called: ---setCellValue--- Here you can set your data based upon the value entered by the user. param(1) - The row number of the displayed table param(2) - The column number of the displayed table param(3) - The value to set the cell ---isCustomFormat--- Allows you to decide whether you should define a custom text format for the cell. param(1) - The cell node as defined by getCellNode param(2) - The row number of the displayed table param(3) - The column number of the displayed table If isCustomFormat returns 1 then the following functions will be called: ---getTextColor--- Return an array of RGB components that will define the color of the text. Each component should be a number between 0 and 255. [R, G, B] for example red is [255, 0, 0]. param(1) - The cell node as defined by getCellNode param(2) - The row number of the displayed table param(3) - The column number of the displayed table param(4) - The text to be displayed in the cell param(5) - The desired number precision ---getTextFormat--- Return 0 for left align, 1 for center align and 2 for right align. param(1) - The cell node as defined by getCellNode param(2) - The row number of the displayed table param(3) - The column number of the displayed table param(4) - The text to be displayed in the cell param(5) - The desired number precision ---shouldGetCellColor--- Allows you to decide whether you should define a color for the cell's background. param(1) - The cell node as defined by getCellNode param(2) - The row number of the displayed table param(3) - The column number of the displayed table If shouldGetCellColor returns 1 then the following function will be called: ---getCellColor--- Return an array of RGB components that will define the cell's background color. Each component should be a number between 0 and 255. [R, G, B] for example red is [255, 0, 0]. param(1) - The cell node as defined by getCellNode param(2) - The row number of the displayed table param(3) - The column number of the displayed table ---shouldGetCellText--- Allows you to decide whether you want to override the table view's default functionality of getting a cell's text. param(1) - The cell node as defined by getCellNode param(2) - The row number of the displayed table param(3) - The column number of the displayed table If shouldGetCellText returns 1 then the following function will be called: ---getCellText--- Return a string that is the text to display in the cell. param(1) - The cell node as defined by getCellNode param(2) - The row number of the displayed table param(3) - The column number of the displayed table param(4) - The desired number precision param(5) - 1 if the cell is being edited, 0 otherwise ---shouldGetTooltip--- Allows you to decide whether a tooltip should be displayed when the user selects a cell in the table. param(1) - The cell node as defined by getCellNode param(2) - The row number of the selected cell param(3) - The column number of the selected cell If shouldGetTooltip returns 1 then the following function will be called: ---getTooltip--- Return a string that is the text to display in the tooltip. param(1) - The cell node as defined by getCellNode param(2) - The row number of the selected cell param(3) - The column number of the selected cell ---isReadOnly--- Return a 1 to make the cell read only. Return a 0 to allow the user to edit the cell. param(1) - The row number of the displayed table param(2) - The column number of the displayed table
View full article
One of the new features in FlexSim 2018 Update 2 is the ability to use distributed CPUs for the Experimenter or Optimizer. Those cores can exist on any machine that meets the following requirements: The machine is accessible by IPv4 address The machine has FlexSim installed The machine is running the FlexSim Webserver (version 18.2.0 or later) on port 80 The machine meets hardware requirements to support running the specified number of simultaneous replications. This article describes how to use Amazon Web Services to create remote machines that meet the above requirements. Using AWS, you can launch and connect to as many servers as you want, and pay only for the time used on those instances. Anticipated Use Case Using distributed CPUs can significantly reduce the required time to run an experiment if: The time to run a single replication is high (a couple minutes or more) The number of replications to run is high If the time per replication is short, then the increased communication overhead may outweigh the benefit of using distributed CPUs. The communication overhead increases because all CPUs still report results to a single FlexSim process, and that communication occurs over the internet, rather than on a single machine. If an Experiment or Optimization completes in an acceptable amount of time, you may not need to use distributed CPUs. Financial Costs Amazon charges for its services. Costs for running instances (and transferring data out of them) are found here : https://aws.amazon.com/ec2/pricing/on-demand/ Costs for storing data (including AMIs) are found here: https://aws.amazon.com/ebs/pricing/ These instructions include steps to create an AMI, which will likely cost around $1 per month at current rates. It also includes steps for launching high-performance instances, which have an hourly cost. Suitable instances can be as cheap as $0.50 per hour. Note that there are also charges for transferring data from an instance to another computer. Step 0: Complete an EC2 Tutorial If you are not already familiar with EC2 instances, you should complete the following tutorial: https://docs.aws.amazon.com/AWSEC2/latest/WindowsGuide/EC2_GetStarted.html Step 1: Create a Security Group You will need to create a security group with the following rules: Allow HTTP traffic on port 80. This allows incoming connections to the FlexSim Webserver. You can choose which inbound IP addresses to accept. You should make this as strict as possible. The strictest setting is to only allow incoming connections from the current IP address. Allow TCP traffic on ports 9000-9200. This is a Custom TCP rule. Note that you can make this range smaller, if all machines that use this Security Group have fewer than 200 cores. For example, if the biggest machine launched with this Security group has 72 cores, you would only need ports 9000-9072 in this rule. Allow RDP traffic on the default RDP port. This allows you to connect to the instance using remote desktop. Name the Security Group something that shows that this group is related to running FlexSim instances, and add a description if you want. Here is an example Security Group that works, but allows all TCP traffic, and so should only be used for testing purposes: Step 2: Create a Custom Amazon Machine Image (AMI) You will need to create a custom AMI. A custom AMI allows you to launch an instance that has the software you need already installed. To create one, follow these steps: Download the FlexSim installer and the Webserver installer. If your upload speed is slow, you can skip this step. Launch the cheapest instance available, with the Windows 2016 Server Base image. There are probably free-tier instances available in the list Connect to that Instance with Remote Desktop Copy (or download, if upload speed is slow) the FlexSim installer to the remote machine, and run it to install FlexSim. You do NOT need to activate a license. Run FlexSim. This creates a directory that is needed later. Then close FlexSim. Copy (or download, if your upload speed is slow) the Webserver installer to the remote machine, and run it to install the webserver. If using the 2018 Update 2 Beta, be sure to change the Webserver configuration file accordingly. Run the Webserver. It will download a bunch of files the first time it is run. Allow both FlexSim and node.js through the Windows Firewall. To do so, use the Allow an App through the Windows Firewall tool. You will need to browse for both FlexSim and Node.js. Both are in the ProgramFiles directory. Disconnect the Remote Desktop session Go to the list of Instances in the AWS Console From the Actions menu, select Image, then select Create Image: Add a name and description. Click the Create Image button On the next dialog, click the View Pending link, or navigate to the list of AMIs: Once the image becomes Available, terminate the running instance. Step 3: Launching Usable Instances Before running an Experiment or Optimization, you need to be sure that all remote instances you will use are current running. To launch and initialize these instances, follow these steps: In the EC2 Console, choose Launch Instance Select the AMI you created, from the list of My AMIs Choose the Instance Type and quantity Set the Security Group to use the Security Group you created Launch the instance Once each instance is initialized, connect to each one with Remote Desktop. Note that when you launch an instance with a given Key File, the password for each instance will be the password associated with that Key File, so you only need to decrypt the file once. Start the FlexSim Webserver in each instance Once all instances are running the Webserver, you are ready to run an Experiment or Optimization. Author's Note: There is probably a way to make it so that when instances start up, they automatically run the Webserver, so that you don't have to manually connect to each one. I welcome any suggestions or steps for how to make that happen. Step 4: Using the Instances in FlexSim Once you have a list of running instances available, you just need to input their IP Addresses into FlexSim, on the Advanced tab of the Experimenter: Once you have input this information, you just need to click the Experiment or Optimize button. FlexSim will then use the remote CPUs for running replications. Considerations Spot Pricing Amazon offers two pricing models: On Demand and Spot Pricing. FlexSim recommends On Demand instances. Spot instances can be significantly cheaper, but they can also be shut down by Amazon and given to an On Demand user at any time, if On Demand requests exceed the number of available machines. FlexSim does not try to recover from this kind of error, and it may lead to unexpected behavior. CPU Count, RAM, and Disk Space When you pick an instance type, be sure to understand how much ram you will need. If a model requires 4 GB of RAM while running, and you use an instance with 128 cores, be sure that the instance has at least 512 GB of RAM, or don't use all 128 cores. Disk space is usually not an issue. However, if you are using the Store Data on Hard Drive option in the Statistics Collector, you will need to be sure that there is enough disk space to run the model to completion on the hard drive, multiplied by the number of cores. The amount of disk space on each instance also affects the total cost of using this service.
View full article
This Kiva system demo model showcases some of the new AGV/AMR features that were added in FlexSim 2023, including new events and parameters to help with deadlock and allocation failure, and dynamic barrier management. You can update the layout through five parameters, and then click the “Build” button to re-build the system. FlexSim-2023-Kiva-System-Demo.fsm
View full article
UPDATE (January 22, 2021): FloWorks 20.0.5 is now available. Except for critical bug fixes, this is likely to be the final bug fix release for FloWorks 2020. Please consider upgrading to FlexSim & FloWorks 2021. UPDATE (December 23, 2020): FloWorks 20.0.4 is now available. UPDATE (June 15, 2020): FloWorks 20.1.2 is now available. UPDATE (February 4, 2020): FloWorks 20.0.1 is now available. FloWorks 20.0.0 is now available (16 December 2019). This version of FloWorks is intended for use with FlexSim 2020. If you are using FloWorks with FlexSim 2019 LTS, please use FloWorks version 19.0.8. If you are using FlexSim 2019 Update 2, please use FloWorks version 19.2.2. 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 support@talumis.com. About FloWorks FloWorks is a 3rd party module developed and maintained by Talumis BV ( talumis.com). It provides faster and more accurate modelling and calculation of fluid systems than the default FlexSim fluid library. It is especially useful within the oil, gas, and bulk industry both for production and supply chain optimization. This module requires a FloWorks license with active maintenance. For any questions, please email support@talumis.com. Release notes FloWorks 20.1.3 (20 August 2020) All bug fixes included in FloWorks 20.0.2 below. FloWorks 20.1.2 (15 June 2020) Bug fix: Fixed exception in release of Flow To Item. Bug fix: Removed internal output to console. Bug fix: Removed redundant license check in old solver. FloWorks 20.1.1 (23 April 2020) Bug fix: Update script for FloWorks Custom Action activities. Bug fix / improvement: Library grid updated. FloWorks 20.1.0 (17 April 2020) Release for FlexSim 2020 Update 1. FloWorks 20.0.5 Bug fix: All products shown as black in some cases where product color table was broken. Bug fix: Items would sometimes not exit from previously blocked Item To Flow. Bug fix: Network solver gave incorrect result in some models using output ratios. FloWorks 20.0.4 Bug fix: Flow conveyor sometimes lags because of unnecessarily many content blocks. Bug fix: Removed redundant license check in model limit panel. Backwards Compatibility Note: The following change may change the way updated models behave. Bug fix: Several issues in the network flow calculation resolved. Bug fix: Flow pipe passes name instead of product ID in first On Product Out Change after reset. FloWorks 20.0.3 (02 September 2020) Bug fix: Input / output triggers were sometimes scheduled at infinity. FloWorks 20.0.2 (20 August 2020) Bug fix: Set content activity uses FlowTank in code header. Added "Max. content" option to picklist. Bug fix: Process Flow activity did not correctly set relative output trigger amount. Bug fix: Flow item tank reset content at end of warmup. Bug fix: Adding Process Flow activity created module dependency. Bug fix: Documentation for flow processor updated. Bug fix: Update script for FloWorks Custom Action activities. Bug fix / improvement: Library grid updated. Bug fix: Fixed exception in release of Flow To Item. Bug fix: Removed internal output to console. Bug fix: Removed redundant license check in old solver. FloWorks 20.0.1 (04 February 2020) Bug fix: Fixed incorrect berth configurations. Bug fix: Removed popup during startup. Bug fix: MODE_RESTART_FALLING was sometimes incorrectly #define d the same as MODE_RESTART_RISING . Bug fix: Several bug fixes and improved stability for the new (beta) solver. Documentation: updated Tank trigger levels description. FloWorks 20.0.0 (13 December 2019) Feature: Added Process Flow activities for FloWorks. Feature: Added Process Flow templates for Basic Berth and Tank Pool. User request: Added option not to checkout FloWorks license. Bug fix: Removed inconsistent behavior after (de)activating license. Bug fix: Tank level trigger could cause event list to become unsorted. Bug fix: Max. Object Depth setting in FloWorks charts was ignored.
View full article
FlexSim 2018 Update 1 Beta is available. (updated 28 March 2018) To get the beta, log in to your account at www.flexsim.com, then go to the Downloads section, and click on More Versions. It will be at the top of the list. 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. Release Notes Added a Database Connector tool and Database FlexScript API. Updated the Emulation module and added it to the toolbox. Updated object triggers to be dynamically added and executed to improve performance and flexibility. Added an option to store StatisticsCollector bundle data on the hard drive. Added a global preference for date and time formats, which will default to the system's locale settings. Updated the stick() command to be able to get information about the VR headset by passing -1 for the stick number. Added a Box Plot chart type. Added a visual Walls object, which can be connected to A* as a member. Added an option to reverse rows on a gantt chart. Updated how the gantt chart handles colors. Added a time window option to several charts. Improved axis title options on several charts. Added a y-axis range option to the time plot. Output, system, and compiler consoles now wrap lines. Fixed a bug with using local variable "a" within FlexScript lambda commands, such as findmatch(). Backwards Compatibility Note: the following changes may slightly change the way updated models behave. Removed FlowNode, Reservoir, WatchList, and other unused library class objects. Changed transportincomplete() to be more fail-safe so that it only affects the object when called correctly. Fixed an issue with the Rack sometimes receiving items out of order when the upstream object is using a transport. Process Flow Added a Variable shared asset. Updated the Event-Triggered Source and Wait for Event activities to be able to match values. People Added a Waiting Line object and a Wait in Line activity. AGV Fixed a bug with preempting an AGV during a pre-arrival event. Backwards Compatibility Note: the following changes may slightly change the way updated models behave. Improved AGV proximity detection for stop-space-based accumulation. Fixed an issue with reversing direction on accumulating paths. A* Added a routing mode for traveling at right angles only. Added an option for stopping and turning when changing directions. Added an option for routing by travel time. Improved the usability of creating and editing barriers and dividers. Added an option for snapping dividers between grid points. Fixed some visual issues with various components. Fixed a bug with distancetotravel(). Backwards Compatibility Note: the following changes may slightly change the way updated models behave. Improved the accuracy of the calculation of which grid points are affected by dividers. The mechanism for recovering from deadlock has been changed. The path costing system was slightly changed to allow for travel-time-based routing.
View full article
Sometimes data exists in Google Sheets that needs to be brought in to FlexSim. There are multiple ways to do this, discussed in this article. Copy and Paste This is the easiest method to get data from Google Sheets into FlexSim. Here's how it works: Open the desired sheet in your browser Click the top-left corner to select everything. Copy the data (use ctrl-C) Open FlexSim Create a Global Table if you haven't already Ensure the number of rows and columns in the Global Table is large enough to hold the pasted data. Click on the column header for the first row in the Global Table. Paste the data (use ctrl-V) Pros: Quick, easy Cons: Need to resize the global table correctly beforehand, repeat entire process if data changes. Export/Import via CSV This is also any easy method to get data. Here are the steps: Download your sheet as a csv file. In FlexSim, use the importtable() command to dump the csv into the global table. For example: importtable(Table("GlobalTable1"), "data.csv", 1) You could add this code to your model's OnReset trigger if desired. Pros: Quick, table sized to csv data automatically Cons: Repeat downloading csv if the data changes. Export/Import via XLSX You can also download a google spreadsheet as an Excel file. Then you can use the Excel importer as normal. Pros: Quick, table sized to data automatically, many options for configuring Cons: Repeat downloading xlsx file if the data changes Import via Python This method is more advanced and requires some configuration for the model and your Google account. Once complete, however, changes can be pulled in automatically without any manual steps. Follow the Sheets quickstart for python found here: https://developers.google.com/sheets/api/quickstart/python Following this guide walk you through creating a Google Cloud Project and creating credentials for that project. In addition, consider using this modified python file instead. This file creates a get_values method that the model can call, and that method is also called from main(), so it's easy to test in a python debugger: import os.path from google.auth.transport.requests import Request from google.oauth2.credentials import Credentials from google_auth_oauthlib.flow import InstalledAppFlow from googleapiclient.discovery import build from googleapiclient.errors import HttpError # If modifying these scopes, delete the file token.json. SCOPES = ["https://www.googleapis.com/auth/spreadsheets.readonly"] # The ID and range of a sample spreadsheet. SAMPLE_SPREADSHEET_ID = "----- add your sheet's ID here -------------" SAMPLE_RANGE_NAME = "A1:B" def get_values(): """Shows basic usage of the Sheets API. Prints values from a sample spreadsheet. """ creds = None # The file token.json stores the user's access and refresh tokens, and is # created automatically when the authorization flow completes for the first # time. if os.path.exists("token.json"): creds = Credentials.from_authorized_user_file("token.json", SCOPES) # If there are no (valid) credentials available, let the user log in. if not creds or not creds.valid: if creds and creds.expired and creds.refresh_token: creds.refresh(Request()) else: flow = InstalledAppFlow.from_client_secrets_file( "credentials.json", SCOPES ) creds = flow.run_local_server(port=0) # Save the credentials for the next run with open("token.json", "w") as token: token.write(creds.to_json()) try: service = build("sheets", "v4", credentials=creds) # Call the Sheets API sheet = service.spreadsheets() result = ( sheet.values() .get(spreadsheetId=SAMPLE_SPREADSHEET_ID, range=SAMPLE_RANGE_NAME, valueRenderOption="UNFORMATTED_VALUE") .execute() ) values = result.get("values", []) return values except HttpError as err: return [] def main(): values = get_values() if not values: print("No data found.") return for row in values: print(row) if __name__ == "__main__": main() Save the above script next to your model. Create a user command in your model. Format the user command for python and enter the file name and method name. It might look something like this: /**external python: */ /**/"sheets"/**/ /** \nfunction name:*/ /**/"get_values"/**/ The return type of the command should be var which means any Variant type. Use code like the following to clone the data to a global table: Array values = getValues(); // call the user command. Array colHeaders = values.shift(); for (int i = 1; i <= values.length; i++) { Array row = values; row[0] = nullvar; } Table(values).cloneTo(Table("GlobalTable1")); Add the above code to a reset trigger. Pros: automatic once complete, easy to keep data up-to-date Cons: requires complicated setup, some python coding. The script could be adjusted to download additional ranges, and then return all data at once, but that requires some code ability. Import via HTTPS Google recommends you use a client library to access its APIs. However, it is entirely possible to use HTTPS requests instead. This could all be done from FlexScript, with no additional installations required. Pros: done all from FlexScript, no extra installs Cons: very technical Conclusion There are several ways to extract data from Google Sheets into FlexSim. Each has pros and cons. Choose the one that best fits your circumstances. Good luck!
View full article
If you have a contiguous conveyor network you can just route items using Conveyor.sendItem() and FlexSim will guide the item to the destination, passing through inline and side transfers as required for the shortest path. If between some conveyors you use exit and entry transfers, perhaps to easily add elevators and shuttles as transports between them - then you'll normally be faced with adding logic to figure out which exit transfer to go to and which port to take from that transfer - and in a large model that logic can be extensive and hard to maintain. The attached model and library provides commands for automated routing through multiple conveyor sub-sections connected through exit/entry transfers, to conveyor points and to connected fixed resources. This means that you may no longer have to write sendTo code with case statements on each exitTransfer to determine which port an item should exit through – nor possibly need to have decision points with case logic to decide the destination for Conveyor.sendItem(). In the example model three sources create items with random destinations which are routed through the conveyor system, transfers and port automatically to arrive at the correct destinations – some of the ports having transport to perform the move. To make this work in any model you should load the user library which will auto-install a set of user commands and a General Process Flow. The first step is to run the user command ‘createAllTravelMaps()’ which will calculate all the reachable destinations (decision points, stations, pes, attached fixed resources and transfers) from all the conveyor points and entry/exit transfers) along with estimates of the conveytime (from the conveyor class). This information consolidated to create the shortest routes and is stored in a label ‘travelMap’ on each decision point, station, pe and transfer. To make use of the travelMap data there are three additional user commands supplied that are intended to be used directly by the modeller: getNextConveyPoint(thispoint, destination) – returns the next point to send an item to from this point in order to ultimately reach the destination. getConveyExitPort(exitTransfer, destination) – returns the port through which an item should exit the exitTransfer in order to reach the destination. getConveyItemsNextConveyPoint(item, destination) – returns the next point to which an item should travel to reach the destination from its current position on a conveyor. The simple process flow in the example and library is set to listen to the Group members of EntryTransfers and ExitTransfers in order to lookup the ‘destination’ label and either sends the item to the next point or in the case of the exit transfers, overrides the sendTo port with the value from the map. I’ve added some documentation to the user commands which you can access easily via the command helper: ConveyorTravelMaps_0.3.fsl ConveyorTravelMapExample.fsm You may find createTravelMaps() takes a while which is why a progress bar has been added. You may not need all points to be evaluated exhaustively so the option to pass in a flag indicating to only start evaluation from Entry Transfers is given, which will create somewhat incomplete maps for intermediate points. A future refinement would be to account for transport time from exit transfers either by recording the times or providing port list with the expected times. Clearly if you make changes to your transfer positions or conveyor layout you should rerun createAllTravelMaps.
View full article
You might be wondering what data is collected when you use FlexSim simulation software. How is it sent to FlexSim? How is it stored? What is it used for? Can you opt out?   Below you'll read all about it, but for those who can't be bothered:   tl;dr: Our customers have complete control when deciding what data is sent to FlexSim. Any data gathering is easily circumvented, disabled, or avoided.   If that interests you, read below for the details.   Introduction There are four ways your data may be sent to FlexSim, and there are workarounds you can implement for each to avoid sharing any data. Each link jumps to its section below: FlexSim Accounts (contact information) Licensing your software or your local license server (license and computer information) Online communications from the software (license and computer information) Support or model building services (customer-sent data) You can also jump to the Conclusion.   FlexSim Accounts We receive user personal contact information when someone signs up for a FlexSim account, or when an account is created for a person in order to give them a license. FlexSim Account information includes required fields (name, email, organization, country) and optional fields (including title, address info, phone). These data are submitted to FlexSim through web forms. Our website is only accessible via HTTPS, with TLS 1.2 or higher enforced. FlexSim's databases are hosted in United States data centers, and this data is encrypted at rest with LUKS (Linux Unified Key Setup) in default mode aes-xts-plain64:sha256 with a 512-bit key. Data is encrypted in transit with SSL. FlexSim US's CRM is HubSpot, and US contacts are saved there. HubSpot ensures that your data is encrypted at rest. HubSpot's sites and services are accessed via HTTPS and we've configured our account's security settings to require TLS 1.2 or higher. Contacts from outside the United States are forwarded to their regional FlexSim distributor, who operate independently and may use a different CRM. Our websites track usage information to help us improve our marketing and fix site issues. Basic web browsing logging data is collected, such as IP/location information, browser type, session duration, etc. Additionally, if you are logged in to your FlexSim account, we keep download, license, and profile logs. Check out Autodesk's privacy policy. Workaround A FlexSim Account requires a person's contact information for convenience only. If a customer wishes, an account can be set up with a generic name, like "CompanyXYZ FlexSim Rep," and a generic email, like "flexsim@company-xyz.com". Having a real name and email of an actual person is convenient, but also optional. As long as we have a way to communicate with a customer, that works!   Licensing License codes When a client PC communicates with our main license server to activate or return a standalone FlexSim license, it does so over secure HTTPS.   When licensing a local license server using the licensing utility flexsimserveractutil.exe license codes are transmitted in plaintext over HTTP. This means that license codes are transmitted in the clear. The risk to a licensed user is that if your online communications are being monitored your license keys could be compromised, allowing someone else to obtain your FlexSim license keys and potentially use them to activate your FlexSim licenses and consume your seats, leaving you without the ability to activate those seats normally.   If there is ever an issue where a license should be available but for some reason is not successfully activating, customers can contact their local FlexSim distributor for licensing support. These situations can be handled quickly.   License codes are stored in plaintext in FlexSim's main Flexnet Operations server database.   Additional license history information When a license is activated over the Internet, whether by a client PC (standalone license) or when configuring a license server (server license), FlexSim also receives the Windows username of the person logged in doing the action, and the Windows computer name where the license is being activated. When activating a standalone license this information is first AES-256 encrypted before transmission over HTTP. For a license server the username/computer name are transmitted in plaintext over HTTP. Once received by FlexSim, the Windows computer name and username are stored in our database which is LUKS encrypted at rest and are displayed to the customer in their account's license history. The license history allows customers to track license usage and location - a useful feature requested by our customers to help manage standalone licenses shared among multiple people.   When activating a standalone license over the internet, the software also sends basic operating system and FlexSim software version information, which, like the Windows username/computername, is AES-256 encrypted before being transmitted over HTTP. This additional information is AES-256 encrypted at rest.   Workaround We have an alternate method of licensing that applies to both standalone PCs and license servers where a user generates XML requests and manually submits them to FlexSim's website over HTTPS using TLS 1.2 or higher. Licensing by XML avoids the following potential issues: License codes sent in plaintext over HTTP FlexSim receiving Windows username and computer name information, and in the case of standalone licensing, additional operating system and FlexSim software version information. Manual licensing is somewhat less convenient and more time consuming than online licensing - instead of just a button push there are several steps to follow in sequence, including generating requests, uploading requests, downloading responses, processing responses. It is up to you to decide whether easy-online or manual-XML licensing is most appropriate for your organization.   License operations, both automated/online or manual/XML are documented in our article Licensing Procedures.   Online communications Start page FlexSim software has a web-based start page that by default sends basic computer information to FlexSim to request introductory content to display when starting the software. This information includes FlexSim version, and general Operating System properties including Windows version, language, and country. These are used to display appropriate content to the user. For instance, we have localized versions of the start page depending on the country and language settings sent by the client PC. If a computer is licensed, the license information along with Windows username and computer name are also sent, again for a history of license use, and also in the case that FlexSim needs to display specific information only to licensed users, such as expected maintenance windows for FlexSim's main license server, etc.   The start page is enabled by default. The above-described information is AES-256 encrypted and then transmitted to FlexSim over HTTPS using TLS 1.2 or higher. The data remains AES-256 encrypted at rest.   Telemetry A user can also enable additional telemetry as an opt-in feature. This sends additional operating system and hardware information such as CPU, RAM, screen resolution, GPU type and driver version, all of which helps us build an aggregated view of the computer capabilities of our user base. This is useful for development decisions, to make sure we target the simulation software to hardware that is generally available to a majority of our user base. This telemetry info is AES-256 encrypted, transmitted to FlexSim over HTTPS TLS 1.2 or higher, and stored in AES-256 at rest.   Workaround: The start page can be disabled with an in-software setting. Additional telemetry is an opt-in feature. You can read more about online communication in our Sofware License Agreement, item 15. Online Communication. The in-software settings are configured from FlexSim simulation software's main menu > File > Global Preferences > Dynamic Content tab.   Support In the course of using FlexSim simulation software, your simulation engineers may send models or other data to Autodesk's FlexSim support team for help via email, or by posting to this online community. Your employees should only do so according to whatever applicable policies you have in place.   In this online community, questions are asked publicly, allowing our worldwide community and partners to help solve problems and provide answers, insights, and experience. Any information or attachments posted to this community are public.   Workaround Don't post or email confidential data. If you need support but your simulation model contains proprietary/confidential/secret information, you could: Pose a general question without including any attachments. Post a sample model you create that demonstrates the question or issue at hand without using any confidential information. If you have a current maintenance contract, you can also contact your local FlexSim distributor for live phone or web meeting support. You could share your screen so that our support staff could help troubleshoot your issues directly on your PC. In this way you could get the help you need without ever transferring any files or data off your computer.   Conclusion Any data that FlexSim might receive is described above, and any data gathering can be circumvented, disabled, or avoided using the provided workarounds. Our customers maintain complete control when deciding what data is sent to FlexSim. In addition, we're happy to delete any information we may already have on your company or your users. We are responsive to our customer's requests and wish to assure you of our commitment to your privacy and security. Simply contact your local FlexSim distributor with any requests about what data we have about you or to request any deletions.   Thank you for your patience in reviewing this long article! Contact your local FlexSim distributor if you have any questions or concerns.
View full article
This model is a proof-of-concept example demonstrating the integration of FlexSim with Python's Pyomo package to solve the Knapsack Problem. The model simulates a loading process of a logistic company. The truck has a weight capacity of 200 kg. The scenario includes 15 products, each with a specific weight and value. The product details are as follows: The objective is to determine which products to load onto the truck to maximize the total value of goods while ensuring the total weight does not exceed 200 kg. The ProductCreation Process Flow creates the products in a Queue. The General Process Flow has a Custom Code that creates a couple of Maps to store the products weights and values. It sets the capacity variable from the Parameters Table. These three parameters can be passed to python. Then it evaluates KnapsackProblem label on the Process Flow, passing those parameters in. The label is configured to connect to the KnapsackProblem function defined in the KnapsackProblem.py module. This function formulates the Knapsack Problem with Pyomo, solves the program, and then returns the optimal collection of products to be load onto the truck. Since the Decision Variables are binary, once the products are resolved, the values are stored in a Global Table, where 1 means that the product was selected. A Combiner uses this table to set the Component List. A forklift load the products and once completed, the truck leaves. When it enters the Sink a message is displayed showing the total weight and value loaded. Model Parameters There are two parameters that can be changed in this model. One is the Truck Capacity, which is the constraint of this problem. The value ranges from 100 to 300. There are three Global Tables in this model that store a different set of Weights and Values for each products. The table selected for the problem can also be changed using the GUI. Potential additions to this model could use priority for the products or include multiple trucks or constraints such as volume. Requirements to run the model In order to run this model, you need python properly configured, including: Install one of these python versions: 3.9, 3.10, 3.11 Install pyomo and highspy packages: python -m pip install pyomo highspy Make sure the python directory is part of your PATH environment variable. Configure your Global Preferences (the Code tab) to use the associated python version. This model was built in FlexSim 24.0 Knapsack_Problem.zip Troubleshooting If you are getting this error: exception: Code Binding Error: could not bind to function Node: /Tools/ProcessFlow/ProcessFlow>labels/KnapsackProblem Binding string: /**external python: */ /**/"KnapsackProblem"/**/ /** \nfunction name:*/ /**/"KnapsackProblem"/**/ Windows Error Code : 126 Check this post
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
Attached is a simple example of using the GIS Module. It contains a GIS Map with 8 Cities represented as points connected by driving routes. gis_example.fsm The model's Process Flow randomly generates tokens, which create items to be carried by trucks from one city to another. After a delay, the item is removed from the model. This very simple example demonstrates how to use the GIS Module to model movement of items from sources to destinations without any FixedResource objects. All the logic can be done through Process Flow to control what happens in the model. This model also demonstrates the Min Scale and Max Scale properties of a GIS Map object. By default, as you zoom the 3D view in and out, the 3D shapes on a GIS map scale so that they remain the same size on the screen, like abstract flat billboard images. When you zoom far out, because the items remain the same size, they seem really big relative to the map. Similarly, when you zoom far in, because the items remain the same size, they seem really small relative to the map. The Map object has Min Scale and Max Scale properties to cap the scaling up and down of objects as you zoom in and out, so that they will only scale up to a certain size and only scale down to a certain size. This makes it so they scale within a certain range, but don't get too big or too small. If you set both of these values to a particular number, then they will not scale at all, but rather be that particular size.
View full article
Good practice to reduce variance when experimenting is to separate streams of things that might vary in the model so that the random sampling is independent. An example might be that you have a number of processors who are members of the same breakdown profile (MTBF/MTTR object) where the individual breakdowns are dependant on the state of the processor. If during one scenario a processor is used more than before then it may sample the duration and next breakdown earlier, and therefore change the sequence with the other machines sampling of breakdown times, increasing variance. This is because the default setting for the MTBF time fields are using 'getstream(current)' - which means a single stream for the MTBF object, shared across all members. You could try to change this in the MTBF by using 'getstream(involved)' where 'involved' refers to the breakdown member machine. This causes other problems since if you're sampling processing times using the machine's stream too, then the amount of items processed will again change the breakdown times samples. You may judge this to be acceptable, but in a ideal world you'd still want separate streams and may want multiple streams for setup, processing, breakdowns, or subsystem failures. One way to accomplish this is by changing the way getstream() works such that it can generate a stream for any value you pass to it. That might be an object, as the current getstream() accepts, or it could be the string name of the object or it's path. It could also be an array which then opens a number of possibilities: In a breakdown you could replace getstream(current) with getStream([current,involved])   //generates a unique stream number for the MTBF/machine pair* In an Object Process Flow you could replace getstream(activity) with: getStream([current,activity]) // generates a unique stream for the instance and activity pair and works for the general process flow too. For a processing time on a processor instead of getstream(current) you could use getstream([current,"Processing"]) and getstream([current,"Setup"]) to generate two seperate sampling streams. The attached library contains an auto-installing user command that overrides getstream() to provide this functionality. The stream values save with the model. getStream-byvariant3.fsl * This implementation does have some limitations since during an experiment it does not communicate back the master model when trying to create new streams. For this reason you'll want to try and have all possible streams set up before running an experiment or avoid the type of actions that dynamically create the requirement for new streams - so that might be keeping all possible fixed resources and task executers, and hiding/removing them from groups rather than destroying them as the OnSet options of the parameters table do currently. Alternatively if you consistently name the dynamically created instances then the MTBF stream expression could be: getStream([current, involved.name]) Update: I've edited this post and library to use getStream (capital 'S') since the override parameter (var thing) doesn't stay in place and eventually causes FlexScript build errors. So with the updated library you'll need to find/replace from the model tree 'getstream' with 'getStream'.
View full article
FlexSim 2019 Update 2 Beta is available. (Updated 28 August 2019.) To get the beta, log in to your account at www.flexsim.com, then go to the Downloads section, and click on More Versions. It will be at the top of the list. 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. Release Notes Added a Storage System object to improve warehouse modeling. Improved the Rack object. Added more types of racks to the library. Updated the Sketchup SDK to load newer skp file versions. Added a ray tracing render mode. Added a Color Palette tool. Improved the color picker popup. Updated dashboard charts to use color palettes. Added options for showing column names to charts. Added options for showing multiple Y-axes on timeplots and histograms. Updated box plot options for categorizing and coloring data points. Added an option for reordering axis categories on timeplots, histograms, and box plots. Added additional line styles and visualization options to timeplots. Added Table methods for using indexed columns. Added a resetvalues attribute. Added Object getVariable() and setVariable() methods. Updated the SQL IS keyword to work with expressions. Improved performance of SQL queries on tables with indexed columns. Added an array parameter to Math.max() and Math.min(). Added a binary bundle field type. Added a button to Model Settings to export embedded media. Changed the default Person flowitem into separate Man and Woman flowitems. Added options for using the object's color to Person Visuals. Added a changepersonvisuals() command and pick options. Updated the Model Background properties window. Added a right-click option to show/hide model backgrounds from the Toolbox. Added pick options for using lists to the Pick Operator field on the processor. Updated various pick options to use generic label references. Added options to the List for special handling of SELECT values. Added Text options to Quick Properties. Added mean and standard deviation to the statistical distribution popup. Added icons to various pick option menus. Improved the Copy Variable function of Edit Selected Objects. Added the location coordinate system button to the General tab of object properties. Removed the Build menu; its options can still be added to the user toolbar. Changed the run speed slider to behave as a ratio of real time instead of model units per second. Fixed a bug with deleting array data from a node. Fixed an exception with cloning a table without rows. Fixed a bug with applying experimenter triggers. Backwards Compatibility Note: the following changes may slightly change the way updated models behave. Improved the rendering performance of some imported shapes by optimizing their meshes by material. Some mesh customizations may apply differently for some shapes. Charts now ignore null values instead of trying to categorize or plot them. Changed the FlexScript + operator to concatenate numbers with strings. Fixed some FlexScript math operations with numbers and null variants. Fixed an issue with FlexScript downcasting not always type checking properly in certain expressions. For example, "Object obj = param(1);" will now correctly throw an exception if param(1) is a treenode without Object data. Updated the Rack's place offset to be the actual location that the item will be placed. Fixed a bug with labels added during events at time 0 not being deleted on reset. Fixed a bug in Color.random(). Process Flow Changed the scroll wheel to zoom instead of panning the view up and down. Removed the extra outline around stacked blocks. Changed the default option for Release Batch on max wait timer and max idle timer to have Failed unchecked. Organized the ProcessFlow list on the toolbar based on the Toolbox folder structure. Changed Event-Triggered Source and Wait for Event panels to be collapsible. Added an edit field for the number of arrivals on the Scheduled Source. Added a getlastacquiredresource() command. Backwards Compatibility Note: the following changes may slightly change the way updated models behave. Updated Move Object's Preserve Global Position checkbox to preserve location and rotation. People Added an experiment variable for changing the number of objects in a People group. Added a visual indicator to show when objects are acquired by the shift schedule. Added A* dividers to waiting lines and other objects. Adjusted the Staff's walk back to reset position so that it is preempted if acquired by something else. Added a custom window for People Down Behaviors. Added a Keep Person on Transport checkbox to the Transport Person activity. Changed the default Arrivals activities to randomize the created person's visuals. Updated activity subflows so travelers synchronize their speeds when traveling together. Moved copying token labels to the created person to after the people settings labels are added so values aren't overwritten. Added state history tables. Conveyor Improved naming of various objects. Fixed a bug with the height of decision points when created with certain model units. Added a chain texture to conveyor belt visual options. AGV Updated curved path quick properties to be able to specify start and end points. Improved naming of control points and areas. A* Added the A* Navigator to the Toolbox. Updated the A* Navigator Properties window.
View full article
FlexSim 2017 is available. If you have bug reports please email dev@flexsim.com or post a new question to this answers site. If you have suggestions or new feature requests, create a new idea in the Development space. Release Notes Improved FlexScript performance by compiling and executing it as machine code instead of interpreted bytecode. Added new syntax to FlexScript for accessing objects' methods and properties, including dynamic label access. Improved OpenGL compatibility by removing many deprecated function calls and adding support for the OpenGL Core Profile. Added a mechanism for loading DWG data into the tree using the Model Background object. Added a new Snap to Background setting on the 3D view for snapping to points loaded from a DWG file. Upgraded the licensing system to Flexnet Publisher 2016 R1 (11.14). Changed the network licensing system so that you can open multiple FlexSim instances using only one license seat. Added a Quick Library popup to Dashboard views. Added Travel to Location pick option to OnResourceAvailable. Added Export Results to CSV pick option to the End of Experiment trigger Fixed some issues with auto-complete not displaying correctly. Fixed a crashing bug with settablesize() on tables with bundle data. Process Flow Added functionality for snapping activities into the middle of a block. Improved the Activities window, including renaming activities, better filtering options, and locating label references. Added a Billboard setting for Text objects. Added a right-click Edit Activity Visuals option. Added an option to the Create Object activity for positioning an object at another object's location without moving into that object. Added a Preserve Global Position checkbox to the Move Object activity. Updated the Schedule Source table so that it can add labels. Updated the Release Token activity to allow numbers and strings. Backwards Compatibility Note: the following changes may slightly change the way updated models behave. The new version of Flexnet Publisher requires network license servers to be upgraded. They need to use the latest vendor daemon and update the Flexnet Licensing Service. More information can be found in the license upgrade instructions at https://www.flexsim.com/ftp/LicenseServer/ Updated the Separator's order of events (executing OnEntry before Setup Time) to be consistent with the Processor. Users of the mesh api should update usage of GL_QUADS to use GL_TRIANGLES instead. GL_QUADS is deprecated and will not work when using the OpenGL Core Profile. Since the new FlexScript parser compiles to machine code, the order in which parameters are evaluated has changed to be aligned with the x86/x64 calling convention. This means models containing code where parameter evaluation order is important may have changed results. For example, the following code will have different results: myusercommand(duniform(1, 5), duniform(1, 10)) In the x86/x64 calling convention, parameters are evaluated from last to first. In this case, the duniform(1, 10) call will be called first. Since this call changes the state of random stream 0, changing the order of parameter evaluation changes the result. The new parser has a stricter grammar for the == and != comparison operators. The types of the operands must be the same or related. For example, the following code will now give compile errors because it is comparing unrelated types: double x = 0; treenode y = model(); if (x == y) { } This version introduces a new Array type, which is an array of variants, enabling a more feature rich array usage. In doing this, we are deprecating the old array types of doublearray, intarray, stringarray, and treenodearray. Specifically, the old array types are now just aliases for the standard Array type. This means that you can now, technically, put a string into a doublearray and vice versa, because they are all just Arrays. Hence we encourage you to just use Array in your code instead of the old array types. This change has also introduced a problem regarding the Variant type. In previous versions, the Variant could hold each of the four types of arrays, and it had a type value associated with each type, which you could get with the getvartype() command, comparing that value to one of VAR_TYPE_INTARRAY, VAR_TYPE_DOUBLEARRAY, VAR_TYPE_STRINGARRAY, or VAR_TYPE_TREENODEARRAY. Now, however, since we've merged all of those types into one, all of those values would theoretically be the same value, introducing issues if you had code that switches on getvartype(), or in some cases if you had a series of if/else compares on that value. Depending on the specific nature of that code, it would be hard to predict exactly how that code would behave going forward. Thus, we have decided to get rid of those old macros for each array type. Now there is just the macro VAR_TYPE_ARRAY. If you have existing code that uses the older macros, you will get compile errors when you open your model in version 17.0. We do this specifically so that you will be notified of code that needs to be updated. There are also several pick list options in the process flow module that use these older macros. Version 17 includes update scripts that will hopefully update all of those pick options in existing models to use the new VAR_TYPE_ARRAY macro instead of the old macros. With the new FlexScript parser, there are now some differences with how the parser compares a null variant to 0. In the old parser, the following expressions applied: (nullvar == 0) is false (nullvar <= 0) is true (nullvar >= 0) is true In the new parser, the following expressions apply: (nullvar == 0) is false (nullvar <= 0) is false (nullvar >= 0) is false This brings the <= and >= operators inline with the == operator. However, old code will evaluate differently now. The following expressions apply in both the new and old parsers: (nullvar < 1) is true (nullvar > -1) is true The param() command will now return nullvar if the parameter number is greater than the number of parameters passed to the function (previously it returned 0).
View full article
In version 2018 and on, you can make this chart by dragging the Throughput Per Hour by Type template from the dashboard library. If you install the template (available on the Advanced tab), you will see a Process Flow and a Statistics Collector appear in your toolbox. One of the most common questions from FlexSim users is as follows: How do I make a chart that shows the output every hour? You can make this chart in three steps. Configure the Statistics Collector First, you need a Statistics Collector. Make a new one in the toolbox (click the green plus button, select Statistics, and then select Statistics Collector). On the event listening tab, use the green plus button to add a timer event, and configure as shown here: This timer event will fire every hour (every 3600 seconds) in the model. Notice the shared label, that is storing all members of the Processors group as an array. We will use this label in the next step. Once you have configured the timer, then you need to set up the row mode for this collector. We want one row per processor, and we need to use the Processors label as the row value. Since the Processors label is an array, we will get three rows per timer event, each row corresponding to a processor. Finally, we can add the columns. The three columns are as follows: Time - use the pick list to select Model Date/Time from the Time menu Object - use the pick list to select ID of row value from the IDs menu Output - use the pick list to select Statistic by Object from the Object Statistics menu Use data.rowValue as the object value in the popup If you use the pick options to choose these options, then the storage type and display format options should be set automatically. With these three columns in place, we can watch the table populate. Reset and run the model at high speed. Every model hour, you should see a new set of rows appear, one for each processor in the group. The table will look something like this: Configure the Calculated Table The Statistics Collector table from the previous steps is close to what we want, except that the output value always increases as the model runs. But what about the output for just a single hour? To get that value, we can use a Calculated Table. Make a new calculated table, and give it the following query (in the Query field): SELECT Time, Object, ISNULL(Output - LAG(Output) OVER (PARTITION BY Object), 0) AS OutputPerHour FROM StatisticsCollector1 This query uses SQL window functions. Basically, it says that each row's value should subtract the previous row's value for the object. In addition, if that value is NULL (because it's the first row), then just use a value. If you reset and run the model, so that the collector table has at least a few rows in it, click the Update button to run the query. Notice that the Time and Object columns show numbers. This is because the Calculated Table can't infer the formatting of the column. To set the formatting, use the Display Format Tab. You may also wish the table to update every hour, with the Statistics Collector. Make the Chart Now that our data is correct, we can make a chart. Make a new dashboard, and create a Time Plot chart. Point the chart to the calculated table. Let's use the Time column for the X values, and let's use the OutputPerHour column for the Y values. In addition, make sure to split by the Object column. If the calculated table updates every hour, then running the model should create the chart shown at the beginning of the model. Here is the model used to create this chart (should work in 2017 Update 2 Beta or later; beta must be built on or after August 21, 2017). outputperhourdemo.fsm
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
Top Contributors