FlexSim Knowledge Base
Announcements, articles, and guides to help you take your simulations to the next level.
Sort by:
FloWorks 24.1.0 is now available (17 April 2024). This version of FloWorks is intended for use with FlexSim 2024 Update 1. If you are using FloWorks with FlexSim 2024 (LTS), please use FloWorks version 24.0.3 (LTS). 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 [email protected]. 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 [email protected]. Release notes View the full release notes in the online documentation. FloWorks 24.1.0 (17 April 2024) Feature: new "Apply Impact Factor" activity in ProcessFlow. Feature: new "Connect Flow Objects" and "Disconnect Flow Objects" activities in ProcessFlow. All bug fixes in FloWorks 24.0.3 below. FloWorks 24.0.3 (17 April 2024) QuickProperties behavior improved. Fixed invalid manual references. Fixed missing code completion documentation. FloWorks 24.0.2 (6 March 2024) Made activity path references in warning message more clear. Restore missing Flow Trigger Process Flow activities to the library. Fixed Tank level indicator settings for some tank shapes. Add Accumulating checkbox to the Conveyor properties. FloWorks 24.0.1 (5 February 2024) Added vertical splitter to Mixer recipe editor and other small layout improvements. Fixed missing icons in statistics panel pin menus. Flow Polygon Tank property panels fixed and documentation updated. Added "Fill Sideways" property for Flow Polygon Tank. IsMultiProduct setting on Flow Tank is now a proper property. Renamed Flow Tank shapes from Cylindric and Rectangular to Tank and Container, respectively. Fixed "Copy Production Plan" button in Flow To Item properties. Some objects were not correctly reset. ItemToFlow statistics were accessible through .output instead of .input . Breaking changes: Deprecated the input.triggerAmount , input.triggerInterval , output.triggerAmount , and output.triggerInterval properties. FlowObject.stats.input and FlowObject.stats.output now return a Tracked Variable. Cylindric level indicator now expects size of bounding box instead of center and radius. The update script will try to convert these for you. FloWorks 24.0.0 (14 January 2024) All bug fixes in FloWorks 23.0.5 below. Improved warning and error messages throughout Fixed rounding issue in Mass Flow Conveyor
View full article
FlexSim 2024 Update 1 is now available for download. You can view the Release Notes in the online user manual. FlexSim 24.1.0 Release Notes If you have bug reports or other feedback on the software, please email [email protected] or create a new idea in the Bug Report space or Development space.
View full article
Railworks 24.0.1 is now available (02 April 2024). This version of RailWorks is intended for use with FlexSim 2024. Railworks 2023.0 will become LTS, for any use cases with updated bug fixes use the latest 23.0 version available. If you are using RailWorks with FlexSim 2023 (LTS), please use RailWorks version 23.0.6 (LTS). If you are using RailWorks with FlexSim 2023 Update 2, please use RailWorks version 23.2.3. 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 [email protected]. Signal: New feature in railworks This new feature adds a 3D object called Signalized Rail, a track with signals that can control train traffic with precise speed changes, sight and safety distances for rail reservations and signal advances. You can configure signal aspects, sight distance and train safety distance with just this object.For more information read 3Dobjects. Importance of the Signal A signal in a railroad system is a way of controlling train traffic speeds, ensuring safety and maximizing the flow. There are different types of signals for different cases and countries, the most common being speed control signals on sections to prevent train collisions. These signals change their appearance in order to indicate a reduction in speed, and can have different aspects for different speed changes. This type of sign is the new railworks feature. 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 24.0.1 (02 April 2024) Bug-Fixes All bug fixes in RailWorks 23.2.3 below. Features New object:Introducing signalized rails - tracks equipped with signs at their ends for improved traffic control and safety at critical network points. Learn more about signaled rails and practice using them on the 3D objects page. Feature:Take control of your rail network with the new rail signaling control feature. Configure aspect signals, customize their colors, set speed correspondences, and define safety or sighting distances for a more realistic train operation experience. Feature: New picklist options to set destination in MoveTrain and MoveWagon activities. RailWorks 23.2.3 (18 March 2024) Bug-Fixes All bug fixes in RailWorks 23.0.6 below. MoveWagon Label Control Improvements: Enhanced the user interface for the MoveWagon label control. OnPass Speed Alteration Fix: Compositions with wagons attached change speeds correctly and consistently. AssingTo labels on MoveWagon Fix: The creation of a new label works with individual wagons on MoveWagon. RailWorks 23.0.6 (18 March 2024) Bug-Fixes Consistent Parked Wagons Positioning: Wagons now position themselves alongside other wagons more consistently. Rail Reservation Logic Optimized: Improved logic for rail reservation to ensure smooth operation. Refined Rail Control Point Triggers: More precise behavior for RailControlPoint's onPass, onContinue, and onArrival triggers. Smoother Undo Functionality: Improved responsiveness and reliability of the undo function (Ctrl+Z). Automatic Brakes Optimized: Automatic brakes now stop on the correct rail for better train control. Wagon Creation Streamlined: Wagon creation now adapts its position automatically when placed on multiple rails. Copy & Paste Errors Resolved:Fixed exceptions that occurred during copy and paste operations. Train Creation Collisions Addressed: Inconsistent collisions during train creation have been eliminated. Enhanced Locomotive Interaction: Improved interaction between compartments and leading locomotives for more realistic behavior. Departure Rail Control Point Fix: Fixed an issue where moving a wagon wouldn't release the departure Rail Control Point. Automatic Braking Refined: Improved automatic braking for scenarios with low acceleration and high speeds. Multiple Rail Braking Enhanced: Resolved issues with braking zones spanning multiple rails. Limited Station Parking: Locomotives destined to a Station no longer allowed to enter while occupied. Better Composition Positioning on Curved Rails: Movement on CurvedRails is now smoother. Added Locomotive and Wagon icons to FlowItemBin. Modelling fixes: Preventive fixes to improve modelling experience. Performance Enhancements Faster Rail Connections: Optimized rail automatic connection for improved performance. MoveWagon Streamlined: Object selection offers more consistent behavior when detaching wagons from larger compositions. Streamlined ConnectPoint Creation: Made changes to ConnectPoint creation for better performance. Optimized Pathfinding: Enhanced path discovery algorithms to improve overall performance. Status Window Consolidation: Review and behavior correction of status bubble on flowitems and task executers.
View full article
FlexSim 2024 Update 1 Beta is now available. FlexSim 24.1.0 Release Notes 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. 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 [email protected] or create a new idea in the Bug Report space or Development space.
View full article
Hi everyone, recently @Arun Kr posted this idea to add a utilization vs. time chart to the available chart types in FlexSim. I had previously build a relatively easy to set up Statistics Collector for use in our models. I have since cleaned up the design a bit and thought to post it here, since this seems to be a commonly desired feature. utilization_vs_time_collector_24_0_fm.fsm All necessary setup is done through labels of the collector. The first three are actually identical to labels found on the default Statistics Collector behind a state bar chart. - Objects should point at a group that contains all objects the collector should track the utilization for. - StateTable is a reference to the state table that will be used to determine which state counts as 'utilized'. - StateProfile is the rank of the state profile that should be read on the linked objects (0 for default state profile). - MeasureInterval is the time frame (in model units) over which the collector will take the average of the utilization. - NumSubIntervals determines how often that measurement is actually taken. In the example image above (and the attached model) the collector measures the average utilization over the last 3600s 12 times within that interval of every 300s. Each meausurement still denotes the utilization over the complete "MeasureInterval". The graph on the left takes a measurement every 5 minutes, the one on the right every 60 minutes. Each point on both graphs represents the average utilization over the previous hour from that time point in time. - StoredTimeMap is used to allow the collector to correctly function past a warmup time, by storing the total utilized value of each object up to that point. This should no be manually changed. Since this last label has to be automatically reset, remember to save any changes made to the other labels by hitting "Apply". The collector works by keeping an array of 'total utilized time' value for each object as row labels. Whenever a measurement is taken, the current value is added to the array and the oldest one is discarded. The difference between the newest and oldest value is used to calculate the average utilization over the measurement interval. The "NumSubIntervals" label essentially just controls how many entries are kept in that array. To copy the collector into another model you can create a fresh collector in the target model. Then copy the node of this collector from the tree of the attached model and paste it over the node of the fresh collector. I hope this can help to speed up the modeling process for some people (at least until a chart like this is hopefully implemented in FlexSim) or serve as inspiration for how one can use the Statistics Collector. I might update the post with a user library version if I get to creating it (and if there is demand for it). Best regards Felix Edit: Added user library with the collector as a dragable icon to the attached files. Edit2: I noticed a bug while using the collector. Having the tracked objects enter states that are marked as "excluded" in the state table would lead to incorrect utilization values (possibly even below 0 or above 100%). Replaced the library with an updated version that fixes this. Edit3: I fixed another bug that resulted in a wrong utilization value for the first measurement after the warmup time if the object spent time in an excluded state prior to the warmup. utilization-vs-time-collector-library-20250212.fsl
View full article
Attached is an example model that shows how you can use reversible conveyors for routing/sorting of items. ReversibleRoutingConveyor.fsm Traditionally we've sort of warned against using reversible conveyors for purposes other than accumulation buffers. The main reason I've been hesitant to promote alternative uses is that the routing system for conveyors is, and will continue to be, static. In other words, the path finding algorithm to send an item through a network of conveyors to a destination point does not change when one or more conveyors in the system is reversed. Put another way, "for routing purposes, ..., the conveyor is always assumed to be conveying in its original direction." This naturally makes using reversible conveyors for routing more complex. However, as long as you can still work within those constraints, you can actually get the desired outcome. The attached model does this by 'shortening' the routing decision so that it can always route onto conveyors in their forward direction. The attached model sorts items by color by moving them between two conveyor via a reversible conveyor that conveys in either direction as needed. In order to still work within the 'static routing' rule, I split the reversible conveyor into two separate conveyors that are directed into each other. This way, I can route items onto the reversible section by referencing a conveyor whose primary forward direction always diverts from the line a given item is on. The critical element is that I have to always make sure that when one conveyor is moving forward, the other is reversed, and vice versa. I also have to implement some mutual exclusion, blocking some items so they aren't sent to conveyors in opposite directions. This all is done in the process flow. I honestly don't know how close this example is to a real life situation. We've just received some requests for a reversible conveyor that can do more than just accumulation buffers, and routing/sorting is the main alternate example I can think of. This is one way you can achieve such a result.
View full article
FloWorks 24.0.5 is now available (27 August 2024). This version of FloWorks is intended for use with FlexSim 2024. If you are using FloWorks with FlexSim 2023 (LTS), please use FloWorks version 23.0.5 (LTS). If you are using FloWorks with FlexSim 2023 Update 2, please use FloWorks version 23.2.2. For FlexSim 2024 Update 1 or FlexSim 2024 Update 2, please use the FloWorks version starting with 24.1 or 24.2, respectively. 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 [email protected]. 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 [email protected]. Release notes View the full release notes in the online documentation. FloWorks 24.0.5 (27 August 2024) Bug fix: Version 24.0.4 installer contained an incorrect module (.t) file Bug fix: Removed ProcessFlow activities which are only available from 24.1 from the drag/drop library FloWorks 24.0.4 (6 August 2024) Bug fix: FlowToItem was not behaving correctly when an item buffer was used. Bug fix: Fixed a timing issue when FlowToItem got starved while an item was being released. Bug fix: Fixed some rounding issues in event scheduling. Bug fix: Fixed Quick Properties product combo when product has been deleted. Bug fix: Missing states 19 and 20 added to state profile. Bug fix: Fixed several issues in FlowConveyor visualization. Bug fix: Invalid curved FlowConveyor animation fixed. Bug fix: Invalid initial content for Segmented Pipe fixed. Bug fix: "FlowConveyor content changes are not allowed" error (and subsequent exception) fixed. Improvment: Curved conveyor now also supports FlowConveyor length property. Improvement: Tank label hidden in FlowItems (FlowVessel and FlowTruck). Improvement: Cleaned up the variables in the FlowItems' model tree. Improvement: Tank size/position and max content changed for FlowTruck, also as FlowTaskExecuter. Improvement: Slight optimization in preventing unnecessary FlowControl events. Improvement: Added SetMaxContent for FlowToItem and improved handling for Flow Tanks. FloWorks 24.0.3 (17 April 2024) QuickProperties behavior improved. Fixed invalid manual references. Fixed missing code completion documentation FloWorks 24.0.2 (6 March 2024) Made activity path references in warning message more clear Restore missing Flow Trigger Process Flow activities to the library Fixed Tank level indicator settings for some tank shapes Add Accumulating checkbox to the Conveyor properties FloWorks 24.0.1 (5 February 2024) Added vertical splitter to Mixer recipe editor and other small layout improvements. Fixed missing icons in statistics panel pin menus. Flow Polygon Tank property panels fixed and documentation updated. Added "Fill Sideways" property for Flow Polygon Tank. IsMultiProduct setting on Flow Tank is now a proper property. Renamed Flow Tank shapes from Cylindric and Rectangular to Tank and Container, respectively. Fixed "Copy Production Plan" button in Flow To Item properties. Some objects were not correctly reset. ItemToFlow statistics were accessible through .output instead of .input . Breaking changes: Deprecated the input.triggerAmount , input.triggerInterval , output.triggerAmount , and output.triggerInterval properties. FlowObject.stats.input and FlowObject.stats.output now return a Tracked Variable. Cylindric level indicator now expects size of bounding box instead of center and radius. The update script will try to convert these for you. FloWorks 24.0.0 (14 January 2024) All bug fixes in FloWorks 23.0.5 below. Improved warning and error messages throughout Fixed rounding issue in Mass Flow Conveyor FloWorks 23.2.2 All bug fixes in FloWorks 23.0.5 below. FloWorks 23.2.1 (7 November 2023) All bug fixes in FloWorks 23.0.4 below. FloWorks 23.2.0 (10 August 2023) All bug fixes in FloWorks 23.0.3 below. FloWorks 23.1.3 All bug fixes in FloWorks 23.0.5 below. FloWorks 23.1.2 (7 November 2023) All bug fixes in FloWorks 23.0.4 below. FloWorks 23.1.1 (26 July 2023) All bug fixes in FloWorks 23.0.3 below. FloWorks 23.1.0 (12 April 2023) Segmented Pipe: removed virtual content and fixed properties Changed default content of flow tanks and mixer from 50,000 to 1,000. All bug fixes in FloWorks 23.0.2 below. FloWorks 23.0.5 Rounding error mode added to Flow control. Improved error message when new content exceeds max content Added ratios function to FlowComposition Error message doesn't show time when stepping, but shows it when running Bug fix: Flow Pipe "Calculate Max. Content From Size" was not working Bug fix: Statistics nodes content, input and output checked during rate precalculation Bug fix: Flow control group panel Statistics renamed to Tracked Variables Bug fix: FlowComposition interface fixed Bug fix: GetProductTypeAmount function fixed for new flow conveyor Bug fix: Tank full event is not scheduled in some cases Bug fix: Flow rates are not always converted when using non-standard units Bug fix: FlowPipe max content update in QuickProperties also updates the current content Bug fix: Set flow rate activity does not always set both in and outflow rate Bug fix: Level indicator is not allowed to be set to 0 Bug fix: Several Segmented Pipe draw issues fixed Bug fix: Names of FloWorks ProcessFlow activities were made more consistent with FlexSim style Bug fix: Set Product Type activity shows list of defined products when using a product table Bug fix: Name dropdown of ProcessFlow statistics popup also working for FloWorks activities Bug fix: Fixed On Full / On Empty event sometimes firing twice for the same tank top / bottom FloWorks 23.0.4 (7 November 2023) Bug fix: Fixed several errors in Flow Conveyor content calculations Bug fix: Additional checks on input / output and triggers when rounding content Backwards Compatibility Note: The following change may change the way updated models behave. Bug fix: Fixed an issue with binding of interface classes. This sometimes caused replications to get initialized incorrectly in an existing FlexSim experimenter instance. FloWorks 23.0.3 (26 July 2023) Bug fix: Module dependency shows invalid module version number All bug fixes in FloWorks 22.0.7 below. FloWorks 23.0.2 (12 April 2023) Moved flow control to toolbox Support time series, level triggered event and workability in Tools.create and Tools.get Added context menu option to disable time series in toolbox Added dot syntax to create flow controls, get the default flow control, and request recalculation of a flow control's network All bug fixes in FloWorks 22.0.6 below. FloWorks 23.0.1 (16 March 2023) All bug fixes in FloWorks 22.0.5 below. FloWorks 23.0.0 (6 January 2023) Improvement: FlowConveyor snapping improved between conveyors. Improvement: Made FlowConveyor properties available in property tables. Improvement: Extra FlowConveyor options added, such as virtual length support. Improvement: Compare Properties enabled for all active FloWorks objects. Improvement: Toolbox items "Level Triggered Event" and "Time Series" support disabled icon. Improvement: MassFlowConveyor supports stacked products. All bug fixes in FloWorks 22.0.4 below (please note the Known Issues information there).
View full article
FlexSim 2024 is now available for download. You can view the Release Notes in the online user manual. FlexSim 24.0.0 Release Notes For more in-depth discussion of the new features, check out the official software release page: FlexSim 2024: Workspaces, Person Visuals, USD Support, and more If you have bug reports or other feedback on the software, please email [email protected] or create a new idea in the Bug Report space or Development space.
View full article
FlexSim 2024 Beta is now available. (Updated November 20) FlexSim 24.0.0 Release Notes 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. 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 [email protected] or create a new idea in the Bug Report space or Development space.
View full article
MQTT is a communication protocol designed for IoT devices. Clients (the devices) connect to a Broker which allows them to publish (send) and subscribe (receive) messages. Each message is associated with a Topic. Each client can choose which topics to use for publishing and subscribing. Usually, the MQTT broker discards messages once they are sent to all subscribers. However, a publisher can mark a message as "retained." This means the broker will keep the last message for that topic and make it available to other subscribers. Only the most recent message is retained. When developing a digital twin, you may need to access these retained messages. This article describes how to do that using FlexSim's Python connection. This article is not meant as a comprehensive guide, but as a starting point, which you certainly will modify for your circumstances. Here are the python scripts and FlexSim model used in this example: MQTT.zip A quick note: since MQTT is a device communication protocol, support for MQTT in the Emulation module is in progress. This article describes how to import data from an MQTT broker like any other file/database/http server, rather than connecting for Emulation purposes. Step 1: Gaining Access to an MQTT Broker Your facility may already have an MQTT Broker running. In the end, your digital twin will need to connect to that broker to retrieve the latest retained messages. However, for testing, or if you don't have an MQTT Broker yet, you can easily get one. One possibility is to use Docker to run the EMQX Broker. However, there are dozens of brokers and installation steps You can download Docker Desktop here: https://www.docker.com/products/docker-desktop/ Once docker is running, you can use the following command in a terminal to download and run the EMQX Broker: docker run -d --name emqx -p 1883:1883 -p 8083:8083 -p 8084:8084 -p 8883:8883 -p 18083:18083 emqx/emqx Note that this command runs a Linux container, so if Docker is in Windows mode, you'll need to switch before running this command. Step 2: Publishing Messages to an MQTT Broker A real facility will have many publishers and subscribers. However, for testing, it can be convenient to create publishers and subscribers that you control. Once your broker is running, you can use code like the following to create a publishing client: https://github.com/emqx/MQTT-Client-Examples/blob/master/mqtt-client-Python3/pub_sub_tcp.py For this example, I created two clients that publish tabular data: one that publishes a set of "raw materials" available for use in the process, and another that publishes a set of "finished goods" available to fulfill orders. To create some data, run the finished_goods_client.py and raw_materials_client.py files for a few seconds each. Note that both of these clients mark the messages to be retained, so FlexSim can access the latest message, even if neither client is actively running. Step 3: Writing a Python Script to Retrieve Messages This approach is demonstrated in fs_client.py, shown here: import paho.mqtt.subscribe as subscribe import json def get_retained_msgs(topics): auth = { 'username': 'emqx', 'password': 'public', } msgs = subscribe.simple( topics, qos=0, msg_count=len(topics), retained=True, hostname="localhost", port=1883, client_id=None, auth=auth, keepalive=5) if type(msgs) == list: return [json.loads(m.payload) for m in msgs] else: return [json.loads(msgs.payload)] if __name__ == "__main__": topics = ["python-mqtt/raw-materials", "python-mqtt/finished-goods"] print(get_retained_msgs(topics)) Run this script to verify that it returns the latest data from the two publishers. When FlexSim calls this function, FlexSim can convert python Lists and Dictionaries into FlexSim Arrays and Maps. So you can return complex data structures directly to FlexSim. Step 4: Writing a User Command to Call the Python Command In FlexSim, create a new user command, and edit the code. Be sure to toggle the node for external use, and set it to the following: /**external python: */ /**/"fs_client"/**/ /** \nfunction name:*/ /**/"get_retained_msgs"/**/ To use Python like this, you need python installed on the path. You also need the paho-mqtt package installed globally. Finally, you need to verify that your global preferences indicate the correct version of Python. For more information on connecting to python functions, see FlexSim's documentation: https://docs.flexsim.com/en/23.2/Reference/DeveloperAdvancedUser/ConnectingToExternalCode/ConnectingToExternalCode.html Step 5: Writing a User Command to Write Messages to Global Tables In this example, the messages we are interested in store tabular data, so it makes sense to store the data in Global Tables: Array tables = ; Array topics = ["python-mqtt/raw-materials", "python-mqtt/finished-goods" Array msgs = getRetainedMessages(topics); for (int m = 1; m <= msgs.length; m++) { Table fsTable = tables[m // header code elided; see example Array msgData = msgs .data; Table msgTable = Table(msgData); msgTable.cloneTo(fsTable); // header code elided; see example } If you run this new user command, you can see the latest data pulled in to FlexSim. Conclusion This example shows just one way you could import data from an MQTT broker into FlexSim. In addition, the kind of data you import or what you do with that data is up to you as the user.
View full article
When presenting and/or demonstrating a FlexSim model, it is often useful to have the model running in a loop that uses a flypath for a motion path. That way, you can more easily talk to the model while it runs, or leave it running unattended on repeat. The model below provides the code and settings needed to do that. In order to add this capability to your model, you will need to add a few things: A user event called EndTime. This setting will affect how long the model runs before resetting and running again. The First Event Time setting is where you can enter the number of seconds before this happens. The Event Code setting is where you can add custom code from the attached example model, found in the "event" tab. Model trigger code within OnRunStart and OnRunStop. This code can be found in the attached example model. A global variable called demo_mode. This can be set to 1 to enable the demo mode functionality, or set to 0 to disable it. Running the model with demo mode disabled is the same as how the model normally functions. Thanks to @Phil BoBo for helping to develop a solution for this. Also, the model requires FlexSim 23.2 or newer to work properly. presentation_demo_mode.fsm
View full article
FlexSim's Webserver is a query-driven manager and communication interface for FlexSim. It allows you to run FlexSim models through a web browser like Google Chrome, FireFox, Internet Explorer, etc. Since the FlexSim Web Server is a basic service to allow FlexSim to be served to a browser, you may decide you want a way to proxy to this service through a full service web server that you can control security and authentication through. This guide will walk you through proxying to the FlexSim Web Server through Apache web server. Install the FlexSim Web Server Program Download and install the FlexSim Web Server from https://account.flexsim.com Edit C:\Program Files (x86)\FlexSim Web Server\flexsim webserver configuration.txt Change the port from 80 to 8080 Start the FlexSim Web Server by double clicking flexsimserver.bat Test the server by going to http://127.0.01:8080 It should look like this: Install Apache Web Server for Windows Download Apache x64 from https://www.apachehaus.com/cgi-bin/download.plx Extract the httpd-<version>.zip file you have downloaded Go into the httpd-<version> folder you have extracted and copy the Apache24 (or Apache25) folder to C:\ Install Apache Dependencies Make sure you have the Microsoft Visual C++ 2008 SP1 package installed. You can get it here: https://www.microsoft.com/en-US/download/details.aspx?id=26368 Download the vcredist_x64.exe package and run the installation Configure Apache Open C:\Apache24\conf\httpd.conf in a text editor Look for the following lines in this configuration file and remove the # character #LoadModule proxy_module modules/mod_proxy.so #LoadModule proxy_http_module modules/mod_proxy_http.so #LoadModule proxy_wstunnel_module modules/mod_proxy_wstunnel.so Those modules should now look like this: LoadModule proxy_module modules/mod_proxy.so LoadModule proxy_http_module modules/mod_proxy_http.so LoadModule proxy_wstunnel_module modules/mod_proxy_wstunnel.so At the bottom of the httpd.conf file, add these 3 lines and save the file: ProxyPass / http://127.0.0.1:8080/ ProxyPassReverse / http://127.0.0.1:8080/ AllowEncodedSlashes On Run Apache Web Server In a file explorer or CMD line prompt, browse to the C:\Apache24\bin folder and run httpd.exe Now that you have the FlexSim Web Server proxied through Apache, you may decide you want to configure Apache to handle security, authentication and customization. Since this is out of the scope of this guide, you can find details on the Internet that can guide you to setting these customizations up. A few resources you may consider: https://community.apachefriends.org/f/ https://stackoverflow.com
View full article
FlexSim's Webserver is a query-driven manager and communication interface for FlexSim. It allows you to run FlexSim models through a web browser like Google Chrome, FireFox, Internet Explorer, etc. Since the FlexSim Web Server is a basic service to allow FlexSim to be served to a browser, you may decide you want a way to proxy to this service through a full service web server that you can control security and authentication through. This guide will walk you through proxying to the FlexSim Web Server through Nginx web server. Install the FlexSim Web Server Program Download and install the FlexSim Web Server from https://account.flexsim.com Edit C:\Program Files (x86)\FlexSim Web Server\flexsim webserver configuration.txt Change the port from 80 to 8080 Start the FlexSim Web Server by double clicking flexsimserver.bat Test the server by going to http://127.0.01:8080 It should look like this: Install Nginx Reverse Proxy From a browser, visit http://nginx.org/en/download.html Download latest stable release for Windows Extract the downloaded nginx-<version>.zip Rename the unzipped nginx-<version> folder to nginx Copy the nginx folder to C:\ Double click the C:\nginx\nginx.exe file to launch Nginx Test Nginx by going to http://127.0.0.1 It should look like this: Configure Nginx to proxy to the FlexSim Web Server Open C:\nginx\conf\nginx.conf in a text editor Find the section that says: location / {    root html;    index index.html index.htm; } Edit out the root and index directives and add a proxy_pass directive so it appears like this: location / {       proxy_pass http://127.0.0.1:8080;    #root html;    #index index.html index.htm; } Save the nginx.conf file Reload Nginx to Apply the Changes Open a command line window by pressing Windows+R to open "Run" box. Type "cmd" and then click "OK" From the command line windows, type the following to change to the nginx directory: C:\nginx>cd C:\nginx and press enter Now, type the following to reload Nginx: C:\nginx>nginx -s reload Test the FlexSim Web Server Being Proxied by Nginx From a browser window again go to http://127.0.0.1 You should now see the FlexSim Web Server interface proxied through Nginx Now that you have the FlexSim Web Server proxied through Nginx, you may decide you want to configure Nginx to handle security, authentication and customization. Since this is out of the scope of this guide, you can find details on the Internet that can guide you to setting these customizations up. A few resources you may consider: https://forum.nginx.org https://stackoverflow.com
View full article
This demo model shows the type of material handling logic that would be found in Bombay sorter system. This tiered conveyor system has products lined up in rows, then drop onto the next conveyor below while staying as a row. More a proof of concept than a fully-featured sample model, FlexSim users can use this as a springboard for more complex horizontal loop conveyor systems. A Bombay sorter (also known as a flat sorter) is a horizontal loop-style sorter. It's used for high-speed automated sortation of small, lightweight items, such as pharmaceuticals, books, and other small parcels. The chutes or cartons are located below the sorter, and when the product is in position, the doors swing open like a trap door to divert the product to the correct location. Bombay-sorter-demo.fsm
View full article
In the attached model we use a Timetable and two MTBF/MTTR objects to define Schedule Loss, Availability Loss (breakdowns) and an element of Performance loss due to short stops (state Down). The processor sends 'bad' items to port 2 based on the send to percentage which account for QualityLosses. The processor's 'best' processing time per part (5 seconds) is stored as a label, while the processing time itself is a triangular distribution with the minumum as 5 seconds - so it also contributes to performance loss. When the Type of the item changes a setup time occurs which is the final contributor to performance loss. Two state profiles were added to the processor - one to track production time and another for availability. An object process flow on the processor detects production profile state changes (between On and off shift) and regular Flexsim state changes and determines the availability state that should prevail. A user command getOEEstat is used to access the values which it calculates on demand and stores in a label on the processor called statsMap. The syntax for this command is: getOEEstat(myMachine,"OEE") The list of stats: "ScheduleLoss","AvailabilityLoss","PerformanceLoss","QualityLoss","IdealProdTime","AvailabilityRatio", "QualityRatio","PerformanceRatio", "IdealProdTime", "RunTime", "OEE", "TEE". A group was used to indicate which objects have their OEE tracked, and a stats Collector reads the group members and adds rows at reset. Finally Performance Measures were added for the stats for processor 1. Processor_OEE_2.fsm 2023-08-22 Update: Added 'TEE' stat.
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 demonstrates a method of giving a task executor a set of tasks (or jobs) to accomplish in a specific sequence by referencing information stored in a global table. In this case, an operator needs to move boxes between queues in a very specific order. The global table defines the order of operations, with each row representing one job. The row contains necessary information about the job: the item to be moved and its destination. These jobs are to be carried out in order, row by row. First, Product1 will be moved to Queue1, then Product2 to Queue2, Product3 to Queue3, Product1 to QueueOut, and so on and so forth. Any modifications made to this table will directly modify the model’s behavior. The logic behind the process flow is relatively simple: a single token loops through a task sequence, with the operator completing a job with every loop. Assign Labels activities are used to get information about the job from the global table and attach that information to the token. The “Assign Labels: Get Table Data” activities reference the current row in the global table to access and store information about the current job (the item name and its destination). The “Assign Label: Item” activities use custom code to search through a group containing all the queues in the model until it finds the item matching the item name from the global table. The task sequence directs the operator to travel to the item’s queue, load the item, travel to the destination, and unload the item. The token’s labels contain the information that is needed for these activities. After this sequence is completed, the label “row” is incremented so that the next row in the table will be used for the following job. Although this demo model shows an operator moving boxes between queues, this method of acquiring data from global tables to define an order of operations can be used in a variety of other applications. GlobalTableDemo.fsm
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
Top Contributors