You are on page 1of 546

What's New?

Version 3.14 (June 2012)


Bug Fixes
1. The Scheduled Arrivals mode on the Patient Arrivals object sets the ApptTime label correctly again. 2. Added getelapsedtime() command. This returns the amount of time that has passed since either the model started, or the warmup time ended. 3. Used getelapsedtime() in a number of utilization calculations and picklists including: Area Occupancy Staff Group Utilization Group Member Utilization Object State User-defined values and Custom Displays 4. If code is edited but does not have any template code in it, it is given "Custom Code" text automatically.

Verison 3.12 (May 10, 2012)


Bug Fixes
1. Fixed GlobalProcesses so that they do not throw exceptions when they occur 2. It is no longer possible to import a model that was made in a different version 3. The Help button on the Path Node's Parameters window now opens the correct help page for each tab 4. Updated the comment header on several pickoptions so that GetRequiredGroup() is demonstrated 5. Added some commands to the documentation 6. Fixed syntax errors in the Activity Start Condition pick-option called "No Staff Currently Allocated to Activities in List" 7. Fixed syntax errors in "Stop or Resume Flow" pickoptions 8. The GlobalProcess Parameters GUI no longer shows the "There is already an object named X" message when it shouldn't 9. Fixed the getwarmuptime() command so that pick-options that calculations that are based on warm-up time are more accurate. 10. Fixed a bug with the numeric precision being set to 0 (which, in turn, caused other problems in a model). 11. Updated the Area Occupancy Level dashboard widget so that it is update when the model stops running.

12. GlobalProcesses now have global variables created to point to them when a model is opened. 13. Changing the name of a Location in the model will now change most references to that Location in Global Processes and Tracks.

Version 3.1 (April 6, 2012)


Bug Fixes
1. Put some 3d shapes back in that were missing from 3.0 (baby, baby in bassinet, man in bed, woman in bed). 2. Redesigned the "Based on Probability" pick-option so that the user can select the number of entries in the array. This fixes an error that was reported frequently that said that the percentages didn't add up to 100. 3. The Excel import process no longer reports "Import Complete" if something didn't import correctly. 4. Fixed the .csv and .txt files that are generated when a Track is exported. There were problems when a file was exported, edited in Excel, saved, and then reimported. 5. The warning message in the Shift Schedule GUI about Groups and Members is no longer shown at incorrect times. 6. Fixed the ItemConveyor's GUI so that it highlights/de-highlights the selected conveyor section correctly. 7. Fixed the Item objects so that their table shape is shown now. 8. Changed the Item objects so that their default shapes are all color-changeable. 9. Removed extra print statements. 10. Fixed an exception that could occur when tasks were re-dispatched from Groups to members. 11. Fixed an exception in the Experimenter results that occurred if all replications returned the same number. 12. Fixed the TaskExecuter (staff, equipment, transports) so that they can be preempted if they are kept, but are idle. 13. Fixed a bug that was causing Shift Schedules to not repeat correctly in some cases. 14. Fixed a bug in the 2.7-3.0 model update code that was placing PatientProcessing objects at z-location of 0, instead of whatever z-location they previously had. 15. The Message/Item Destination field can now use its access variables correctly. 16. The Message/Item Destination field can no longer use "patient's location" as a drop-down list. (But the location can still be selected in the Advanced Functions.) 17. Fixed a bug in the PatientQueuing object that was causing a single patient to be "released" multiple times. 18. Updated/clarified some tooltips throughout the GUIs. 19. Fixed a bug in the Custom Arrivals that was causing extra patients to arrive if two time periods started at the same time. 20. Users no longer need to press "Apply" in order to have the PatientArrivals

Parameters GUI recognize the difference between two arrivals in the Appointments tab.

New Features
1. Updated the Track Manager so that certain fields are disabled and/or cleared out when needed. 2. Added SortModel() command and included the functionality in Tools|Maintenance. 3. The ItemConveyor is no longer a roller conveyor by default. It is now a more abstract series of arrows. 4. The help now includes commands that start with capital letters in the index pages. 5. Added getobjecttype() command. 6. Updates to model update code. 7. Added checkbox to the Predecessor list in the Track Manager and Global Process Manager so that users can easily enable/disable predecessor lists. 8. Added "Dispatch Companions" pick-option to Message Received trigger. 9. Added an arrow on the floor of the WaitingArea and WaitingLine so that the user can easily see what direction the patients will be facing. 10. Removed a lot of unnecessary fields from the Staff/Equipment/Transport Advanced Editor GUIs. 11. Added "Create Activity for Multiple People" pick-option. 12. Added getnumresources() command. 13. Patients now record how long they had to wait for Locations or Resources to become available. This is available in the output files. 14. Added "Total Wait Times by Track" stacked bar-graph to the Dashboard. 15. Added new 'scale' shape for Patient Processing objects. 16. Added Infant Scale 3d shape (not yet available in the drop-down list). 17. Added ClockTime column to output files. 18. Updated Tutorial models. 19. Added "Based on Location" and "Center Port connection" pick-options to some Advanced Functions for tracks.

Version 3.0 (January 30, 2012)


Bug Fixes
1. Fixed a bug with the Global Processes (formerly Global Activity List) that sometimes allowed activities from previous runs of the model to stay active in subsequent runs, causing unexpected activities to take place. 2. Changed the name of the Pass to property on Group objects to Task Assignment Strategy for clarity. 3. The AVI maker now warns users to of Microsoft Vista and Windows 7 to switch to the Basic or Classic theme during recording, as special window effects and transparencies can cause performance issues.

4. User Events can now accept the 00:00:00 time string formatting in the First Event Time property field. 5. Fixed a bug that would sometimes cause a Milestone to be created from the select or add new option if it was selected from the Milestone drop down menu. 6. Increased consistency of object properties tabs; the Stats tab is now correctly displayed for all objects and any objects that had a General tab, it has been renamed to Visuals. 7. Fixed a bug with the Output files option that could cause a crash when trying to write to a file that has not been opened yet. 8. Fixed a bug in Staff Groups OnResourceAvailable trigger that incorrectly managed a Staff member's return to home base functionality when carrying more than one Item. 9. Fixed a bug when Verbose is checked when creating Model Documentation from the View menu that would cause the program to crash. 10. Fixed a bug that would incorrectly display an error message when clicking on a Spline point, after creating a new Path node that has a connection. 11. Graphical display of reporting variables, such as Milestones, performance measures and Dashboards will only be drawn if the value is greater than zero. 12. Fixed a bug that sometimes wouldn't allow the user to rename Model Layouts from the Utilities tool. 13. In the Experiment Manager, switched placement the Replication: and Scenario: fields for increased clarity. 14. Fixed a bug when using the toolbar run control buttons (Stop, Run, etc.) with an Experiment running, that would cause random numbers preferences to be incorrectly set. 15. Fixed a bug that could cause a saved model with an Experiment defined, to have its start time interpreted incorrectly upon opening the model. 16. Fixed a bug in the Performance Measures tab of the Experiment manager that would cause Performance Measure names to not update when the Apply button is clicked. 17. Fixed a bug in the Experiment Manager that would cause a syntax error upon opening a saved model that had an experiment variable that used the XX replacement system. 18. Fixed a bug in Performance measure calculations that would not properly account for locations or staff that were disabled as part of experiment variable. Calculations were being made based on the total number of staff and locations, rather than the actual number available. 19. Fixed a bug that would require at least one Experiment variable to be defined if the desire was to simply run multiple replications of the model, as is. 20. Fixed problems found in updating v2.77 models to v3.0. 21. Fixed several minor bugs in user interfaces.

New Features
1. The PatientQueuing Layout tab has been updated to be easier to use and to allow the user to specify the direction that rows of chair face. 2. Added "Milestone Times (by Track)" dashboard widget.

3. Various improvements to graphics and animations . 4. Updates to the default Entrance Criteria that will allow patients who have a room reserved to safely enter objects that are upstream of their reserved room without negative consequences. 5. Shortened the default list of milestones. 6. Added password-based login. 7. Added user audit log support. 8. Added Object Tracker GUI (Tools|Debugging|Object Tracker). 9. Placing a new object on a Display that is acting as a floor will automatically create a selection set named after the Display (if needed) and will add the newly-created object to the set. 10. Multiple staff that are required to be at the same node in a path will spread out. 11. Changed the behavior of the Appointment and Custom Arrivals tables in the GUI so that the user can use the arrow keys while editing time cells. 12. Removed unnecessary pick-options from several pick-lists throughout the software. 13. Added many new pick-options throughout the software. 14. Fixed problem of equipment being deallocated too early in a MoveEquipment>Process activity, and yet it's state is still utilized. 15. Improved patient overhead display. 16. Added activity start times to patient's Paramters GUI for ongoing activity display. 17. An open Patient GUI now displays the patient correctly, no matter where it is in the model. 18. Patient Destination can now be a specific location as well as an Area. 19. ItemArrivals now have batch arrivals as part of their interarrival time. 20. Itemtype field for ItemArrival's interarrival time mode can now be an expression. 21. New icons and splash-screen graphics. 22. New "Patient Rounds" pick-option for Custom Activities. 23. Floors are hidden by default for many location types. 24. Modified floor and object colors for improved color separation. 25. Lightened area block colors in order to read the area names in the Flowcharting GUI. 26. Removed "Group" from the default name for equipment and transport groups. 27. Patient Classification tab, originally implemented as part of the Patient Arrivals object, has been moved to the Track Manager. This serves to better organize settings that belong to patients in the model, and also fixes a bug that would sometimes cause multiple arrival objects with individually configured PCI tabs to conflict. 28. The previously required action of making manual connections from Path nodes to patient location objects has been supplimented with a check box on the object's properties. You may still create manual connections between objects and Path nodes, including group objects. 29. Added check box for Arrival at time 0 on the Interrarrival Times tab . 30. A new Item Conveying object has been added to the Library of Objects. 31. Added a new Patient Processing object shape: Bathroom. 32. The Stop Watch icon on the toolbar has had its features expanded. Click the Stop Watch now opens a small dropdown window of available runtime options for the model. Here you will find the model Start time definition, the model Warmup Period

length and the model total run length. 33. Some error messages related to Activity IDs and names have been removed in favor of silently fixing the warnings rather than displaying an error pop up every time. 34. Display objects: A time Display object will be created automatically for new models, located in the upper right hand corner of the grid. New pick options for the Display object have been added to support different time display formats. Management of Display objects has been moved to a new drop down menu element in the toolbar, to the right of the run speed slider. From here you may create new Display objects and more easily manage existing ones. Display objects now have a non-selectable option added to their Properties tab 35. Changed the name of the EmergencyBed to Gurney. Only new instances of objects with this shape should be affected. 36. Replaced the Allocate/Deallocate Activity types with the more flexible Custom activity type. Old models that used Allocate/Deallocate, should not be affected. 37. Elevators: The Elevator object has been redesigned and renamed Elevator Bank to allow a Group of elevators to work together more seamlessly. Elevators now take into account the size of the traveler and the anything it is holding to determine how much space travelers take up. 38. Added the ability to view and edit the number of active locations in an Area via the Flowcharting tool. 39. Due to limited and often misunderstood functionality, the Allocate Patient check box on all activity properties has been removed and replaced with additional picklist option under the Advanced Functions. Only affects new models, older models will have that feature preserved. 40. Added increased appearance customization options to Staff members and Patients. 41. Added new pickoptions (including options to add/remove accessories from a patient) 42. New options to the Staff Requirement table on the track manager, including the new "Keep" feature 43. Extensive revisions to the code behind the scenes for all the activity types which should improve patient state management and runtime performance. 44. Added a terminateactivity() command that is a more complete way of forcing an activity to be completed vs finishactivity() which wasn't intended to be used in this manner. 45. Improvements to the way repeating activities work. 46. Added an Advanced Function for using an expression to define the item/message destination. 47. Integration with the FlexSim 5 Engine. 48. New undo (Ctrl-z) /redo (Ctrl-y) capability. 49. New debugging capabilities, including:

50. An in-line, step-by-step Flexscript debugger. Just go to the code editor and click in the left margin to set a break point. 51. More strict syntax rules for Flexscript, including parameter cardinality and type checking. 52. An event log that lets you see all events that have fired in the model, filter those events, export them to csv, etc. 53. An event list that gives you a view of the list of pending events. 54. A Flexscript code profiler that lets you see what Flexscript functionality is being called, how often, and how much time is being taken up. 55. A new Animation Creator that allows you to create movable sub-components of objects as well as custom animations for those sub-components. 56. New .skp 3D file import capability, for using files from Google Sketchup and Google 3D Warehouse. 57. Improved 3D refresh rate. 58. Improved compatibility with ATI, NVIDIA, and integrated graphics cards. 59. New software-based licensing using Flexnet. 60. Faster and more seamless compiling process, with no creation of a new FlexSim instance. 61. Fixed compiling issues for Windows Vista and Windows 7 62. More detailed, navigable and configurable Experiment reporting, with additional histogram and correlation plots. 63. Support for png, ico and gif texturing on 3D objects, allowing transparency without requiring the .tmp and .tpg files. 64. New all-in-one code editor with tabbing and an apply button. 65. Improved interface for defining Conveyor layout. 66. Fixed AVI Maker for Windows Vista and Windows 7. 67. New and improved xml save features, allowing multiple developers to work on the same model simultaneously, as well as better integration with version management systems. 68. Various improvements for advanced modelers and developers. 69. Much more intuitive manipulation of objects in the 3D view. 70. Users can now click on objects below the grid plane. 71. Improved support for traversing window controls with the keyboard. 72. Improved Find/Replace in Tree feature. 73. Improved refresh rate on table views. 74. Fixed a crashing issue with auto-completion hints. 75. Fixed a bug with renaming labels. 76. Fixed an issue with spline points being invisible if the 3D view has a black background. 77. Several new Flexscript commands for string parsing. 78. You can now Ctrl-Tab to switch between open windows. 79. FlexSim's 3D view now has a "hover" highlight so you can see what object is under the mouse. 80. More descriptive exception handling. 81. Added TASKTYPE_STARTANIMATION, TASKTYPE_STOPANIMATION, and

TASKTYPE_FREEOPERATORS. 82. Animation of the 3D View continues while panning/zooming. 83. Various minor fixes and improvements

Version 2.771 (Sep 17, 2010)


Bug Fixes (v2.771)
1. Fixed problem with Shift Schedules rolling over from one week to the next. 2. Fixed problem with patient overhead displays disappearing at the conclusion of a transfer activity. 3. Fixed the legend on the Milestone Chart of a patient's Properties window.

New Features (v2.771)


Added the following picklist options for the Activity Finished Trigger: Send Staff to Home Base Occupy and Reserve Transport Position Patient on Transport Position Transport at Location Added a new picklist option for the Process Location field titled: Reserve Location Added a new User Condition to the Pass To field option that checks whether the candidate's "reserve" label is currently zero. 8. The simulation minutes displayed in the status bar at the bottom of the screen now takes into account the user-defined simulation start time. 9. The ApptTime and ArrivalTime labels of a patient take into account the user-defined simulation start time. 10. Added two new commands: getsimtime() and getsimstarttime() 1. 2. 3. 4. 5. 6. 7.

Version 2.77 (Aug 13, 2010)


Bug Fixes (v2.77)
1. The Entrance Criteria for Next Patient field for a Patient Queuing object wasn't being checked when a patient to be escorted to another location defaulted to traveling unattended to the Patient Queuing object when no staff member is available. This has been corrected so that now the entrance criteria must be met before travel to the queue is allowed. 2. Fixed problem where defining a Repeat Interval for an activity on a patient track would cause errors at the time the patient exited the model. It is now possible to stop a repeating activity with the finishactivity() command now as well. 3. Added exception handling when staff are not correctly defined, or broken references appear as a result of using same as above activity or previous from group staff

selection options. 4. Time series dashboard graphs now take into account simulation start times as defined by the Tools > Simulation Start Time menu option. 5. Corrections have been made to the stop time field on the main toolbar so that it will correctly display the stop time defined in a model immediately after opening the model. The stop time field will also continue to display a stop time in dd:hh:mm format (if so entered in that format) rather than convert it into minutes. As before, the stop time needs to be entered in terms of any offset to the start time as defined in Tools > Simulation Start Time. 6. The Move Equipment/Transport Process activities have been updated to use the same travel rules as the Process activity in terms of how the staff choose between multiple path nodes connected to a location to travel to, and whether to offset travel from a node to a patient within a location. 7. Fixed problem with the vertical scroll bar in the track managers activity list box. The scroll bar no longer jumps when selecting activities at the bottom of a long list. 8. Fixed the Patient Rounds picklist option in the Activity Finished Trigger. Equipment (if used) are now allocated properly before the start of the rounds. 9. HC based states are now updated on staff members when they are called by Item Class objects for processing and/or transporting purposes. Previously, HC states were only updated on staff members called as part of a track activity. 10. Fixed a problem that could occur in the unlikely event that two or more transfer activities were spawned simultaneously for the same patient. Now a check is made to ensure that only one transfer activity can occur at a time for the same patient. 11. All patient transfer activities now require the allocation of the patient prior to the start of the transfer. This will allow the user more control over when a transfer activity occurs in relationship to other activities that require the allocation of the patient directly. 12. When an activity is added/removed from the activity list in the Track Manager, it now correctly renumbers any "Assigned Activity ID" fields as needed. 13. PatientProcessing objects that are reserved for the patient's return, now correctly transition from a "Blocked" or "Occupied" state to a "Holding For Patient" state. 14. Fixed problem with updating old models occurring on one or two user's computers where the main view panel would become unresponsive.

New Features (v2.77)


1. Added a new time series graph to dashboards for plotting patient attributes, object states, object variables, and global variables over time. 2. A patients total distance traveled is now recorded automatically. Options have been added to show distance traveled for both patients and staff in output files and dynamic dashboards. 3. Added a picklist option to the Pass To field of resource groups that selects resources in a round robin fashion according to their availability. 4. Added a picklist option to the Activity Started Trigger that allows the user to choose a resource used in a previous activity step for the current activity.

5. Added a direct link in the Help menu to the new community site created specifically for FlexSim Healthcare users. 6. Further refinements have been made in an effort to keep staff members from standing on top of each other when multiple staff are performing independent process activities at the same location at the same time. If multiple nodes are connected to the common location, then the staff member will travel to the first, second, third etc. node connected to the location based on whether there are none, one, two, etc. active tasks underway respectively at the time the staff member is called. 7. Output data files can either use decimal points or decimal commas based on the country settings of the computer. In addition, both numeric and text label values can now be written to output files, and there are several good examples for defining Custom Fields within the Output Data Settings interface. 8. Patient and Patient Processing object state profiles have been expanded to include more states (see user manual for more information). 9. The simulation start time can now be defined in minute resolution using Tools> Simulation Start Time menu option. 10. An option has been added to the Hourly Arrivals tab of the Patient Arrivals Properties window allowing the user to specify whether patient arrivals are equally spread or randomly distributed across the hour. Previously, the arrivals were always distributed randomly across each hour. 11. All patient transfer activities now require the allocation of the patient prior to the start of the transfer. This will allow the user more control over when a transfer activity occurs in relationship to other activities that also require the allocation of the patient. 12. Revisions have been made to the online User Manual, including new tutorials. 13. An optometry chair has been added to the list of 3D shapes available for a Patient Processing object. 14. Two new picklist options have been added to the Activity Start Condition field which allows for the inclusion/exclusion of a specific activity completion. 15. The picklist option titled "Choose from a list of areas" for the Patient Destination field is now extremely powerful with its list of selection rules. This option also allows for the continuous reevaluation of the Patient Destination field whenever downstream locations become available. 16. The optimization tool called OptQuest is now available as an optional add-on to FlexSim Healthcare. To learn more, follow this link: http://www.FlexSim.com/products/optquest

Version 2.75 (May 31, 2010)


Bug Fixes (v2.75)
1. Fixed the problem discovered in the basic training model with patients not continuing on to Xray sometimes from their treatment rooms. This bug occurred in the function responsible for transferring a patient from one location to another only if the patient was not able to transfer immediately, but must wait for both an available location to transfer the patient to AND an available staff member for escorting the patient.

2. Reinserted the "Patient Rounds" picklist option in the Activity Finished Trigger field (it was accidentally removed from the 2.703 release). 3. Fixed problem where a patient not using path network walks several feet off the floor from locations with custom shapes. 4. Fixed problem with patients standing off the floor in locations with <none> chosen for their shape. 5. Redesigned the Appointments tab slightly for the Patient Arrivals object properties window, and rewrote some of the tooltips. 6. Fixed problem with the Item Destination field not showing the destination entered by the user when the Track Manager was first opened. 7. Creating/Duplicating/Deleting tracks now refreshes the other tabs in the window consistently. 8. Fixed problem with importing/exporting track activity tables using the Files tab of the Track Manager where Id's were not being converted to row numbers. 9. Renamed the Flowcharting window from "Area Connections" to "Flowcharting" like it should have been all along. 10. Resetting the size and rotation of an object using the context menu (i.e. right-click menu) of the main view now works properly. 11. Fixed problem with the Flowcharting window sometimes showing area blocks for Item class object. 12. Fixed problem with FlexSim Healthcare crashing occasionally when writing outputs to an external file during a model run. 13. Fixed problem with the Start Time and Repeat Interval not occurring at the correct time when the model's simulation time was offset from midnight. 14. The + button for the Activity Started Trigger and Activity Finished Trigger fields will now correctly append rather than replace a selection. 15. The getareastat() and getstaffgroupstat() commands will now accept global pointers for the area and group designations. 16. The "Stop Model Based on Condition" option in triggers has been repaired. 17. Fixed problem with contents of certain fields disappearing/changing when windows were resized with the mouse. 18. Item class objects are no longer automatically connected to the previous item class object found in the model (this cause more confusion than benefits). 19. Whether duplicating the highlighted object or a set of selected objects, the duplicates are offset from the original(s) by 4 grid spacings in the -y direction. 20. Fixed the problem seen with Shift Schedules not going down at the right time sometimes. 21. The default "User Applied Score" found in the Pass To option for resource and alternate groups has been changed from -gettimeinstate(candidate, STAT_PerformingTask) to 0, because it was found to be overpowering the score applied based on proximity and yet proximity is probably the more desired scoring criteria.

New Features (v2.75)

1. Added a Multi Line Text Box widget to dashboards. 2. Added a new option for the Patient Destination field called "Choose From List of Areas" which will choose from a list of areas based on one of two user-defined selection rules: "First Available Location" or "Fewest Occupied Locations". 3. Added a new option for Activity Started/Finished Trigger called "Assign Staff Based on Patient's Current Area". 4. Added a new option for Activity Finished Trigger called "Record Staff Used by an Alternate Group". 5. Added a new option for the Send To field of Item Class objects called Based on Patient s Location. 6. Previously it was necessary to refresh connections in the model by reopening the Flowcharting tool and closing it after a new object was added to the model, or the area of an object was changed. From now on, if a new object is created in the model or an object's area is set to an existing area in the model that already has connections established in the Flowcharting tool, the object is automatically connected according to the connections associated with its new area. 7. The Auto Connect button found in the side bar of the Flowcharting tool was replaced with a Refresh Connections button. 8. Added a Stop/Resume Arrivals to the Down/Resume Functions for Shift Schedules. 9. A simulation start time can now be defined globally in Tools> Simulation Start Time instead of on each of the Shift Schedules as was necessary previously. 10. You can now define a simulation stop time on the toolbar using 00:00:00 format taking into account a modified simulation start time. 11. The warmup time and simulation run time defined in an Experiment now take into consideration a modified simulation start time. 12. There are now user-defined dashboard options for a stacked bar chart. 13. A user-defined option for a line graph dashboards has been added called Patient Data Categorized by Label which uses an option named Record Patient Data found in entry/exit trigger fields to record patient data during a run. 14. Created a shorter list of commands in the Help menu titled Most Used Commands.

Version 2.70 (April 16, 2010)


Bug Fixes (v2.70)
1. Fixed the, "By Time of Day," option in several of the picklists, and renamed the option to: Based on Simulation Time. It now correctly accounts for simulation start times that are offset from time zero as defined by the user when creating shift schedules. The pick option allows use of the following terms when referencing simulation time: year, week, day, hour, minute and shift, with a shift being further defined as any given number of minutes. 2. Fixed problem with shift schedules switching from an available state to a down state between 00:00 and 00:15 even when the table displayed an available state. 3. Tooltips have been rewritten to improve the clarity and accuracy of the text displayed.

4. The picklist options designed to stop a model run based on a condition were not working correctly with the Experimenter. This has been fixed with the new picklist option titled, Stop Model Based on Condition. 5. Fixed problem with the library view not opening after the, Close All Windows, option is selected in the main view's context menu. 6. Fixed crash which sometimes occurred while running a model and simultaneously trying to save dashboards, tracks, etc. It's still not a good idea to do such things while a model is running, but at least it does not crash the software now. 7. Fixed crash which occurred when a model was stopped using script in the Entry Trigger of a Patient Exit object. 8. The, By Percent, picklist option had a typo that mistakenly defined the random number used to obtain an empirical value as ranging from 0 to 102 instead of 0 to 100. This has been corrected. The P() option used a different function which was always correct. 9. Path names as displayed in a path node s properties window are now updated correctly to reflect any changes made to node names. 10. The main view window is now refreshed after variables are copied using the Utilities Tool, so that visual effects that depend on certain variables will be recognized immediately. 11. Since the Presentation Builder does not work properly when the main view is orthographic, a warning message is displayed indicating such. 12. The, return, flag for equipment is now included in the import/export track files as it should be. 13. Information entered on a Label tab is now applied when the Apply/OK button is pressed immediately after entering data. Previously, it was necessary to first click off the cell the data was typed into. 14. Fixed problems found in many of the dashboard widgets: Axis label display errors on line graphs Displayed values for Object Queue vs. Time charts were sometimes off depending on size of graph boundary The words In-Process have been changed to Census in graph titles Fixed conflicts between global variable definitions and definitions associated with other libraries (custom user libraries that might be added by advanced user/developers). Fixed error with auto-naming activities with milestone names when another activity was clicked on in the list before Apply button was pressed. This is okay to do now. When a user erroneously checked the, Reserve Current Location, box (previously named Hold room during absence) when transferring a patient from a Patient Arrivals object to another location, it caused the Patient Arrivals object to stop creating patients. The problem has been solved by ignoring the request to reserve a Patient Arrivals object. The list of Global Variables is refreshed when the window's Apply button is pressed. Previously missing break; statements have been added to the end of each example script line in the, Based on Multiple Cases, option in the Next Activity field. This

15. 16. 17.

18. 19.

20. 21. 22. 23. 24.

addition will prevent the example script from rolling over to the last case rather than executing a singular case as intended. The, Based on Percentages, option for the Next Activity field did not convert the ID number to a row number as it should have. The script to convert ID number to row number has been inserted. Fixed problems encountered when answering, Yes, to, Save before creating new model? prompt prior to opening a new model. Fixed problem with the Start Activity Condition field returning false when an expression is entered and then erased. Fixed the problem where activity parameters were not being properly updated between scenarios when parameters were defined as variables in the Experimenter. The staff selection box in the table on the Maintenance tab of a location will now resize correctly to match the size of the Staff column.

New Features (v2.70)


1. The HASP driver install is no longer included as part of the FlexSim Healthcare software installation function. This was done to satisfy the request of some users who needed a silent install of the software. The HASP driver is needed for the dongle key to be recognized by the computer, and only needs to be installed once (i.e. not with every new version of the software). First time users will need to install the HASP driver through the Start > All Programs > FlexsimHC > Install HASP Driver option that will be available after installing the FlexSim Healthcare software. 2. The free trial version downloadable from the FlexSim.com web site, can now run models of any size. It will not allow models to be modified or saved that have more than 20 objects, 2 tracks, or 12 activities per track. More of the Tools have been made available in the trial version, but valid analysis will continue to be frustrated by forcing the random number generator to repeat the same stream for every run. There are also blocks on importing and exporting data. 3. New shortcut key combinations have been added for those users who like to use the keyboard rather than the mouse where possible. Here's a complete list of keyboard shortcuts now available in the software: Ctrl+Up arrow to increase run speed (rounds off to the nearest reasonable speed, so it's easy to change to 1= real time, if desired) Ctrl+Down arrow to decrease run speed Ctrl+Left arrow to reset the model Ctrl+Right arrow to step through events of model Ctrl+Space bar to toggle between run and stop the model run Ctrl+T to open the Track Manager Ctrl+R to open the Flowcharting tool (R as in "Routes" - sorry but F is reserved for Find) Ctrl+D to duplicate the highlighted or selected objects in the model view window Ctrl+C to copy selected text, tree nodes, or table cells to the clipboard

Ctrl+V to paste text, tree nodes or table cells from the clipboard Ctrl+F to find text within a text editor Ctrl+Z to undo typing within a text editor Ctrl+Y to redo typing within a text editor 4. The File > Import Another Model menu option, has been added to allow users to combine two or models into one big model. This is a handy feature when multiple users are working together to build the same model, or a single user desires to build and validate small models of individual parts of a larger system, and then combine the models into one big model at a later date. After choosing the menu option, a file open dialogue window appears allowing you to browse for a model you wish to import into the currently opened model. After the import is finished a report pops up listing what was imported and what was not. During the import process, if a duplicate track name is encountered, rather than import the duplicate track; the activity list of the duplicate track is scanned for unique activity names, and any unique activities are appended to the end of the existing track s activity list. Global Activity Lists are managed the same as Tracks. For all other objects, duplicate named objects are skipped and only uniquely named objects are imported into the existing model. The report will list exactly what was imported, what was skipped, and what activities were appended to an existing list of activities. 5. Removed the speed control editor button from the toolbar now that shortcut keys are available for quickly setting the run speed. 6. Toolbar buttons are spaced more uniformly, tooltips have been improved, and some icons have been modified to improve the look. 7. Spinner controls (up/down arrows next to a numeric entry field) have replaced basic numeric edit fields to allow the user to quickly change values with the mouse. 8. A new tool has been added (see Tools > Color Palettes) allowing you to create your own or modify existing color palettes. Wherever color is applied in a model (e.g. patient shirts, location floors, dashboard bar charts, etc.), you will be able to reference the color palettes you ve defined. The color palettes are saved with the model. 9. Unnecessary prompts to save a current model before opening or starting a new model have been suppressed if no changes have been detected since the last save. You should not depend on the software detecting every change to the model, and always save your model before opening or starting a new model. Better safe than sorry! 10. Global tables, shift schedules, random interrupts and global activity lists can now be referenced in script anywhere in a model using auto generated global variables having the same name as the name of the object declared in the Tools menu. 11. When a new Shift Schedule is created, it will have no operational time defined, rather than the previous default which arbitrarily had the hours between 8am and 4pm MonFri marked as operational time. This often was overlooked by users. 12. Dashboard widgets can now be edited by simply double-clicking on the widget, and can be deleted by simply hitting the delete key. These options are still available through the context pop-up menu accessed via a right-click on the widget. 13. The, Occupancy Levels by Area, and, Staff Utilization by Group, dashboard

widgets are explained in detail with a context menu option (right-click) named, View Calculation. 14. User-defined bar charts are now recalculated on a repeating time interval specified by the user, rather than with every screen refresh making them much faster and easier to set up. The following options are available as a starting point for defining your own bar charts: Group Member Utilizations Tabular Data Total Throughput by Area Current Occupancy by Area Total Throughput by Location Current Occupancy by Location User-defined line graphs are now possible, with the following options currently available as a start: Patient Data Categorized by Label Tabular Data 15. Object Queue vs. Time graph has been changed from a line graph to a solid area graph which is a much nicer way to view queue/time plots. 16. Reduced the number of options by consolidating options having similar behavior. 17. Alphabetized some of the longer lists of options. 18. Now that the user has the flexibility to create and define their own palettes, all triggers that change color of objects do so using a specified color palette and index. 19. Pick option templates have been modified to improve their readability and to hide unnecessary text from displaying in the field when the template view closes. More choices have also been added to many of the pop-up lists found in template views. 20. There's a text display option for the Display object that will show the current values for year, week, day, shift, hour and minute. Since the displayed values take into account the simulation start time as defined in Shift Schedules, it is helpful in checking your understanding of the terms as they are used in the new, Based on Simulation Time picklist option. 21. A new option named, User Configurable Resource Selection Algorithm, has been added to the list of options in the, Pass To, field for group objects . It is very flexible and can be configured to handle just about any conceivable requirement for choosing a resource or group to pass resource requests to. Because of its flexibility, this new option is the default option for groups. You should consider updating the, Pass To, field of groups in your existing model to this new picklist option. Be sure and review the several default entries associated with this option to ensure they are what you expect. If you do not fully understand the entries, open the script editor for the field after choosing the option to read more about how the option was designed. 22. Added options for setting and incrementing labels, table cells, global variables, and patient attributes in triggers. 23. Added option for recording patient attributes and other data in triggers. 24. Improved the options available for reading/writing to tables and external files.

25. There is a new selection choice available called, OriginalResource, for the, Preempted Task Reassignment," found in the User Configurable Resource Selection Algorithm option for Pass To fields. By choosing, OriginalResource, you are stating that you want tasks preempted away from a resource to be given back to the same resource to be done later. The default is to give the task to the resource's primary group to be passed to another available resource. 26. The <delete> and Custom Code options have been added to all advanced function fields. 27. Added a new option to the Entrance Criteria for Next Patient field that will only accept patients having a specified label with a value matching a list of specified values. The option is named, Only patients with specific label values. 28. The arrows connecting area blocks are sized to better match the default scale. 29. The default positioning of area blocks is improved to avoid blocks from hiding behind other blocks. 30. The default color of an Area block is a derivative of the first location within the area, but care is taken to not have a block color so dark that its area name cannot be read. You may now change the color and width of an area block by double-clicking the block to open a small editor. 31. The slide out bar on the left side of the flowcharting window has been redesigned to hopefully improve understanding of the available options. 32. Area blocks can be connected with click-drag from one block to the next, or by using a click-click from one block to the next. The yellow indicator line will now disappear after a connection is made, rather than remain visible which caused confusion before. 33. It's now easier to distinguish between creating a brand new track with no activities and duplicating an existing track with activities. On the Tracks tab there is now a separate button to Create, Duplicate and Delete a track. There are also up/down arrows to change the rank of a track in the list. 34. The tooltips now describe things better and more accurately. 35. Some fields have been given shorter names that better describe their function. We realize it can be frustrating when field names you've become accustomed to change, so we will refrain from future changes unless absolutely required. Here's a list of new field names with their previous name shown in parenthesis: Patient Destination (Patient's Next Area) Reserve Current Location (Hold room during absence) Fixed Cost (Total Activity costs = ____ $) Variable Cost Rate ( + _____ $/hr) Allocation Priority (Resource Allocation Priority) Preempt Resources (Preemption Rule with two picklist options is now converted to a check box) Allocate Patient (Patient's exclusivity is required) 36. The Process Time field has been modified to allow either numbers or script to be typed directly into the field itself, or a per-defined option to be selected from a list and then modified. The, Choose a Statistical Distribution, option is handy when using a

37.

38. 39. 40.

41.

42.

distribution function with unfamiliar parameters because you ll be prompted for the required parameters. Although this Process Time field is similar in form to the other fields found on the Advanced Functions window, it has some differences. Rather than click on a button (e.g. paper icon button) to open the so-called template view for a selected option to read or modify, simply click on the top option found in the dropdown list. The top option in the list is always associated with the current entry for the field. The AI button to the right of the field is used to open a full text editor for viewing or modifying the raw script associated with the current entry for the field. Activities will automatically have the activity ID attached as a prefix to the name of the activity. When the activity ID is changed, the name is automatically updated with the new ID number. Hopefully, this will help users avoid mistakes made in declaring predecessors by reading an activity's name rather than its actual ID number, because the two will now coincide. With the recent changes made to the Track Manager, the need to access the Advanced Functions will be infrequent. Expressions can now be used in both the Start Time and Repeat Interval fields for an activity. This will allow you to use statistical distributions to define the times if desired. A slight change to the timing associated with checks to start an activity has been made. When the list of activities is scanned for possible activities to start, only the predecessors and start time of the activities are checked. All activities passing these two checks will be considered for an actual start. It's at this time that the Activity Start Condition will be checked to determine if the activity can continue. Previously, the start condition was evaluated at the same time as the other two checks during a scan of the entire activity list; however this limited flexibility with activities being repeated. Each repetition of a repeating activity will now check the condition before starting, but will continue with the repetitive chain of events regardless of the condition of a single repetition. The startactivity() command also checks the start condition for an activity before actually starting it. A new activity type called, Decision Point, has been added for use when a decision between two or more activity steps in a track needs to be made during run time. This is the formalization of an existing option to declare the next activity to begin upon completion of a current activity using the, Next Activity, field found in the Advanced Function editor for all activity types. Previously, when the return box was checked for Equipment or Transport resources used in an activity, the return request was dispatched to the first staff member involved in the activity upon completion of the activity, regardless of any other considerations. The return functionality now works this way: Upon completion of the activity, a return request is only generated if there is no other allocation request pending for the equipment/transport involved. If the return request is generated, and the involved staff member is allocated to another activity, then the return request will be dispatched to the staff member'ss primary group. In addition, if the primary group is also a member of a group such as an alternate group, then a quick check of the primary group's other members will be made, and if no other members are currently available, the request will be dispatched to the alternate group. In all cases, the

43.

44.

45.

46. 47. 48.

49.

50.

51.

original activity with the, return, box checked is considered complete at the end of the process time, and the return task is considered a totally separate and independent task. A change has been made to the way resources are selected when a, previous from option is used to define an activity's resource assignment. Until now, and regardless of the state of the resource, the resource request was always dispatched to the first resource from a particular group previously used by the Patient. Now, with one exception, if the resource member used previously is in an, Off Schedule, state at the time of the request, the request will be dispatched to the primary group of the resource. If the primary group is also a member of a group, such as an alternate group, the other members of the primary group are checked first for an Off Schedule state in order to determine whether the dispatch will go to the primary group or to the alternate group. In a Transport Patient > Process activity, when a transport moving a patient arrives at its destination, it will be released immediately unless it's retained by the activity using the, same as above activity, command, or the box is not checked to, return, the transport upon release. Patient and staff walking speeds are now dynamically updated during run time to equal the slowest included object's defined speed . For example, if a staff member with a normal speed of 80m/min and a wheelchair with a normal speed of 70m/min are used to transfer a patient with a normal speed of 60m/min, the staff member will travel at 80m/min to the wheelchair, push the wheelchair to the patient at 70m/min, and then push the patient in the wheelchair at 60m/min to the transfer location. The walking speed of patients can be defined by track type using the Visuals tab of the Track Manager, and the speed for staff, equipment and transports can be defined by individual resource using the primary group s Properties window. New Command finishreplication() added to the Stop Model Based on Condition, option found in trigger fields. New Command getarea(object); If the object is a location, you'll get the location's area. If the object is a patient in a location, then you'll get the area of the patient's location. New Command getareastat(area, stat); If stat = 1, gets the number of active locations within the area. If stat = 2, gets the number of currently occupied locations within the area. If stat = 3, gets the percent occupancy for the area calculated in the same manner as the Occupancy Levels by Area dashboard graph. New Command getcensus(object, trackname); Gets the number of patients in a single location (e.g. getcensus(WaitingRoom)), or in the entire model (e.g. getcensus()). If a valid trackname is given, only the number of patients for that track is counted (e.g. getcensus(WaitingRoom, Track1)). Otherwise, all patient types are counted. New Command getstaffgroupstat(group, stat); If stat = 1, gets the number of active staff members in the group. If stat = 2, gets the number of currently utilized staff members. If stat = 3, gets the staff group utilization percentage calculated in the same manner as the Staff Utilization by Group dashboard graph. New Command getthroughput(object, hourly, trackname); Gets the number of patients who have exited a single location or the entire model. If a valid trackname is given,

52. 53. 54.

55.

56.

57. 58. 59. 60. 61. 62. 63. 64. 65.

66.

then only the number of patients for that track is counted; otherwise, all patient types are counted. If the hourly flag is 1, then the value returned is a per hour figure. New Commandstoparrivals(object); Stops a PatientArrivals or ItemArrivals object from generating any new arrivals, while letting any patients or items already in the object leave. New Command resumearrivals(object); Resumes the generation of arrivals at a PatientArrivals or ItemArrivals object that was previously stopped with the stoparrivals() command. New Command setrunspeed(speed); Sets the simulation run speed. Value entered is the number of simulated minutes per one real minute. A value of 1 would run the model in real time. This command will also update the slide bar and value displayed on the toolbar above the view window. Even though more than one path node may be connected to a location, travelers will, by default, use the shortest path when traveling to that location. However, by checking the, Alternate Exit, box found in the arrival node's Properties window, it's also possible to have travelers leave a location using a different path node than the one they used to reach the location. When multiple staff members, using the path network to travel to a Patient Processing location, arrive, they'll occupy the path nodes attached to that location in the same order as they are assigned in the staff table for that activity. In other words, the staff member associated with the staff assignment defined in the first row of the staff table of the activity, will be directed to travel to the first path node connected to the location, and the second staff member to the second path node, and so on. If you forget the order you connected the path nodes to the location, you can view the connection order number by changing the Information Display to, Show object names (see right-click context menu for the view), and then clicking on a path node to reveal its order number. Improved positioning of multiple staff while escorting and transporting patients. Improved staggering of multiple staff assigned to the same process. Improved staggering of multiple patients arriving at the same location. Multiple patients arriving at a Patient Processing object that has <none> selected for its shape will be positioned according to a grid pattern across the footprint of the object after they have entered the object. New picklist options have been added to facilitate repositioning of patients arriving at locations. A custom transparency level can now be assigned to a Display object for text and floor displays. Patient Arrivals and Patient Exit Objects: The Properties window has been updated to resemble the Patient Queuing and Patient Processing objects' Properties windows. The Users Manual is in need of a rewrite, but there are a few new sections added recently that are worth reviewing. The Users Manual > Modeling Tools > Track Manager contains a good explanation of what a track is, and at the bottom, there's a short description of the various Activity Types. The Users Manual > Modeling Tools > Track Manager Advanced Functions contains

short explanations of the Advanced Functions. 67. Sample Model: This release includes a sample model of a small emergency department. The model is named Demo_ER_1.fsm and can be found in the user>Documents>FlexsimHC Projects folder. The model uses a CAD drawing for a floor plan. There are two simplified tracks defined in the model: Basic and Xray. The Basic track has the following activities: arrival, registration, triage, bed placement, nurse assessment, nurse/doctor consult, doctor exam and discharge. The Xray track is the same up through nurse/doctor consult, then xray, return to bed, and discharge. Walking paths are used to connect the various locations in the model.

Version 2.50 (December 11, 2009)


Bug Fixes (v2.50)
1. Fixed bug with equipment not being disconnected from network when Connect with Path Network box is unchecked. 2. Fixed bug so new resources added after the Connect with Path Network box has already been checked will also be connected. 3. Fixed problem where experimenter was not updating variables associated with the Next Activity field and global variables. 4. Removed visual glitch (green box) shown on dashboard line graphs. 5. Fixed bug with repetitive activities not always working when running a model for multiple replications. 6. When staff members are preempted away from a patient, the patient s state is now changed to Waiting For Staff. 7. The problem with requests getting caught in an infinite loop when passed between multiple resource groups, as could happen when using Alternate Groups, has been fixed. Group members should now be able to contain both resources and other groups without a problem. 8. A problem with assigning labels to patients has been fixed by forcing the user to always create labels on a patient using the Patient Classification tab of the Patient Arrivals Properties window. 9. Fixed problem with some models requiring the Track Manager to be opened and the Apply button clicked before they would work. 10. Fixed bug with Patient Processing objects not allowing multiple patients even when the Maximum Occupancy was set greater than 1.

New Features (v2.50)


1. A check is now made for availability of both a location and a staff member when a patient is to be escorted to their next area. When there is a PatientQueuing object connected, the patient will walk unattended to the queue. Previously, only a location needed to be available to keep the patient from walking unattended to the queue. 2. Added option to lock the position of walls to avoid accidentally moving them. 3. User can now easily specify where preempted tasks are re-dispatched for completion

(or force the preempted task to be completed by the resource that was preempted). 4. When the OK button is pressed on the Track Manager, the window will no longer close if an error is detected in the activities, to avoid having to reopen the window to fix the error. 5. Improved the elevator dispatching logic so that the elevator will only pick up passengers who are going in the same direction as current riders (capacity is limited by a user-defined number of passengers). The animation has been improved to not shut the door in the face of multiple passengers loading/unloading at the same floor too. 6. Added an option to send staff on patient rounds using a single activity step. One or more staff will be sent to locations in a specified order to perform a task. If equipment is specified, then the staff will first pickup the equipment, and carry it with them to each of the location listed. A process time expression will be evaluated for each staff at each location they visit to determine their stay time. Only locations that are in a chosen state (i.e. vacant, occupied, etc.) will be visited. 7. User can now add their own custom fields to the automatically generated output files. The custom fields can be calculated derivations of existing fields, or completely new data. The number of decimal places for numeric variables written to output files is now based on the global setting for decimals rather than always using 2 decimal places. 8. Added an option to easily modify patient arrival rates as one of the experiment variables. 9. The Excel table importer now has options for importing Global Tables, Arrival Tables (e.g. Hourly Arrivals, Appointments), Object Tables (e.g. maintenance tables, component lists, user-defined label tables, etc.), and Shift Schedules. A new field has been added to the importer called Post Import Trigger which can be used to execute script immediately following the importing of the tables from Excel. 10. As with locations, resources (i.e. staff, equipment, transports) are visually marked with a red square around their base when not available. 11. Added a new overhead display option for patients that will only show the in process activities for the patient currently highlighted in the model. This has been made the default rather than the option that shows the overhead display for all patients concurrently. 12. Added option in Next Activity Chooser picklist to choose an activity based on occupancy of a given location. 13. Added option in triggers to dynamically create patients on the fly (e.g. babies in the maternity ward). 14. Made it possible to reset, create, and/or delete activity steps dynamically during runtime. 15. Added a checkbox to return equipment and transports to their home base (primary group) after finishing the activity they are used in. The return activity is a separate task sequence with low priority so as not to delay the completion of the initial activity step. 16. An individual or group of selected objects can now be duplicated with a right-click option on the 3D model view, or with the quicker but largely unknown Ctrl-D shortcut

key combination. 17. Added many new 3D shapes to the dropdown lists for Patient Processing, Group, Item Queuing and Item Processing objects. 18. Replaced the AutoConnect button with a Flowcharting button on the main toolbar. This new button opens a window that allows you to graphically map the flow routes of the various patient types in your model. Multi-colored connection arrows are available to help you define and organize your routes. The routes are defined by area rather than location, so they are quick and easy to create. There is still the option of having FlexSim automatically try to create the connections between areas in your model based on information derived from the track definitions. However, as you ve probably discovered, these automatic connections are not always what you want, so the new flowcharting tool will help you make your connections correct right from the start, and it is also a very nice way to graphically present your patient flows to others. 19. The Probably Early Exit option for the Patient Leaves Early field on the Patient Condition tab of a Patient Queuing object s Properties window has been expanded to allow for a conditional query as well as a probability percentage in deciding if a patient leaves early. The option will also create a user-defined label on the patients leaving early so that the patients can be identified in the output reports. 20. A new simplified format for the csv file used to import and export patient tracks between FlexsimHC and Excel has been developed. Multiple resources defined for the same activity step can now be specified in one cell by separating the list of resources with a comma. If the Next Activity Chooser and Activity Start Condition fields were defined with a single line expression, they too will be imported/exported. 21. To facilitate quick and easy data entry, two new commands have been included in the software: T() and P(). The first is just a substitute for the triangular() command. However the second, allows you to specify a list of values to be returned based on a corresponding list of probabilities. The format for the data typed into the P() command, is P(, percent1, , percent2, ) for up to nine different values. If more are required, then the dempirical() or cempirical() commands which can reference an unlimited list of values/percents in a global table must still be used. 22. The following commands have been added: drawobjectfloor(), finishactivity(), firstavailableresource(), firstpreemptableresource(), getobjectstate(), getiteminstate(), gettraveldistance(), getwarmuptime(), reservelocation(), scanactivities(), setcolorbypalette(), setnextarea(), setnumlocations(), setnumresources(), setobjectstate(), startactivity(), timestringtominutes(), toid(), torownum(). 23. Resources being used to transfer a patient are no longer allowed to be preempted; however when the transfer is complete, the request queue is immediately evaluated for preempting requests that have not been satisfied. 24. Using the mouse wheel to change the height of a selected object will restrict moving the object below floor level. 25. The Display object is a nice way to make a floor. Any objects dropped onto the floor will be placed at the same height as the floor by default. This can be useful in multifloor models. 26. The Utilities tool window can now be used to change the ranking of nodes in the model tree. This is useful for those who like to organize the list of objects in the tree

view. Keep in mind that the order of the objects listed in the model tree is the same order they are listed in many of the dropdown lists. 27. The Maintenance shape for staff objects has been enhanced to include a cleaning cart. It is now the shape of woman pushing a standard cleaning cart. 28. The User-Defined Bar Graph in a Dashboard has been made more general to include all object types. Another picklist option has been added to show an example of collecting and graphing data found in an object label.

Version 2.01 (September 18, 2009)


Bug Fixes (v2.01)
1. Allocate and Deallocate activity types are now working properly. 2. Simulation start time offset can now be globally defined and saved with a model. All time related fields will now take the start time into consideration. 3. Prev/Next buttons found in many of the gui windows have been debugged and now work properly to hopefully speed up the editing process across several objects. 4. More error trapping has been incorporated into the code to avoid as many exception errors as you may have previously experienced. 5. Sometimes, patient and location states were not getting set when they should. This has been fixed. 6. The Track Properties editor (now called the Track Manager) had problems refreshing properly, and therefore would occasionally assign data entered within one field to another field. This was usually manifested by staff appearing to travel to a wrong location for a process. It also caused problems with patients getting stuck at a given location as they were trying to get to advance to an area not allowed for the track. These problems have all been fixed by fixing the way data is presented and saved by the Track Manager interface. 7. The options on the Utilities window for creating saved Selection Groups and saved Layout Configurations did not work. This has been fixed. 8. Fixed the problem with background images disappearing randomly. 9. Fixed the problem with bad global pointers being generated sometimes when trying to rename staff, equipment and transports. A more robust approach for the autogeneration of global pointers for object names and area names has been developed which hopefully has eliminated these problems. 10. Clicking Apply/OK on the Shift Scheduler after making changes in the graphical Work Schedule table view used to erase the changes. This has been fixed. 11. The bugs with the Hourly Arrivals table method for generating patient arrivals into the model have all been fixed. 12. Staff connected to an Alternate Group were not included in the previous from ___group picklist options. This has been corrected. 13. The bug with repetitive tasks not always repeating properly has been fixed. 14. The warmup time event now correctly resets all variables requiring reset. 15. The deallocate activity didn t always release staff like it was supposed to. This has been fixed.

16. Fixed bugs with the Presentation Builder and AVI Maker, so they now work correctly with the main view. 17. The same as above activity option now works for transports.

New Features (v2.01)


1. More predefined dashboard widgets are available. 2. Many new user-configurable Dashboard graph and text display widgets. 3. Each widget now has a data structure associated with it that the user can take a look at and export if desired. 4. The user is prompted to save dashboards before closing when changes were made. 5. Multiple dashboards within one model are now allowed. 6. Staff now use a default picklist option for returning to their primary group object when unavailable due to Shift Schedules or Random Interrupts 7. Resources such as staff, equipment and transports can now be chosen for an activity in a variety of user-defined ways using the Pass To field found on the Advanced Group Editor, the Advanced Resource Editor, and the Alternative Group Editor. The purpose of the field is to allow the user to choose the manner in which activity requests (otherwise known as task sequences) are dispatched from group to group and from group to resource. In other words, which resource connected to the group specified for the activitys staff, equipment and transport requirements do you want to be chosen for the activity. The default option for the Pass To field for resources and resource groups has been improved to handle more situations in a more realistic manner, but you may easily change the selection criteria with the new picklist options provided. 8. The previous from ___group option that has been available for assigning staff to an activity is now an available option for assigning equipment and transports as well. 9. The Patient Tracks and Track Properties windows have been combined and renamed Track Manager. This was done to reduce the number of windows required to be opened at one time. The new Tracks and Files tabs on the Track Manager essentially make up what used to be the Patient Tracks window. The Tracks tab now allows you to change the name and order of existing tracks. When adding new tracks, you can make a blank track or create a duplicate of an existing track you have highlighted in the list. 10. The Visual tab of the Track Manger lets you change and visualize more parameters than before. Be sure to check out the new options for dynamic overhead displays for patients in the model. The frame selector is handy for viewing the available frames for a patient should you decide to override the defaults and assign your own frame to a patient for a specific event in the simulation. 11. The Labels tab has been changed to restrict users from adding their own labels this way. User-defined patient labels are meant to be added using the Patient Classifications tab of the Patient Arrivals edit window. Youll note that there are two new system defined labels for a patient: ApptTime and ArrivalTime. These are used when the patients arrive by appointment as defined on the Patient Arrivals object. A patients scheduled appointment time versus their actual arrival time may be useful to

you to query within your model. 12. It is now possible to import and export tracks using a simplified tabular format (ref. Comma Delimited (*.csv) option) making it very easy to export track activity lists to a table in Excel for reporting purposes, but it also gives you the possibility of making changes to the activity list within a worksheet, and re-importing your changes to test in the model. If a track with the same name already exists, the imported information will replace existing information for the track; otherwise, a new track will be created and the imported information applied to it. 13. For simplification purposes, the Activities tab of the Track Manager window will now only show those fields which are applicable to the chosen activity type. Youll notice for instance, that the Process Location field only shows up once youve selected staff for a Process activity. This is because the Process Location is only used when staff are going to be utilized during the process time, in which case the staff must first travel to the Process Location before the Process Time begins. These little changes, plus a host of sanity checks that get executed when the Apply button is pressed, will hopefully help the user to avoid data entry errors. 14. Youll notice a new checkbox on the Activities tab for the first five process activity types that is Patients exclusivity is required. If a patients exclusivity is required for a process, then the patient will be allocated for the process. This means the patient cannot be allocated by any other process while allocated by this process. Normally there are multiple activities that can be occurring for a single patient at any given time. 15. The Transport Patient > Process activity type now has an option requiring the staff return the transport to the transports group object after dropping off the patient. This option is invoked by simply checking the box labeled return found in the Transport selection pane for the activity. 16. The Process Location can now be defined with an expression in Advanced Functions rather than just selecting a specific location on the Track Managers Activities tab. This will allow the process location to be determined during runtime according to system dynamics at the time the decision needs to be made. 17. A very powerful field has been added to Advanced Functions called Activity Start Condition. This new option requires that a user-definable condition be true before an activity is kicked off. The condition is rechecked every time the activity list is scanned for another activity to begin, and the user may create custom events to force reevaluation of the list at any time! With this condition field, conditional based activity list traversal within a given track is easier than ever. 18. An Activity Started Trigger has also been added to Advanced Functions giving you the opportunity to modify the parameters of an activity before it starts allowing you to make changes based on the state of the model at the time of the activity. An extensive list of user pick options makes this an easy task. 19. The list of user pick options for Advanced Functions has been expanded to include improved options for making selections based on system state and availability of resources and locations. New options have been added for making decisions based on patient attributes and time of day as well. 20. User-defined milestones are now included in the drop-down list, and saved with the model.

21. The prev/next arrow buttons at the bottom of the Advanced Functions editor can be used to quickly step through the advanced functions of all activities of a selected track. 22. The AutoConnect features now interprets connections based on the full list of Next Areas, and is smart enough not to connect locations to each other within the same area. 23. A global start time for offsetting the simulation clock can be defined and saved with a model. 24. Source code has been streamlined and compiled to improve runtime speed of a simulation substantially. 25. Application code has been removed from user fields to avoid confusion with userdefined options. 26. Global system variables have been separated from user-defined global variable to avoid confusion and provide a clean slate for users to define their own list of global variables if they want. 27. A large number of commands have been added that allow a user to easily modify resources, tracks and locations on the fly. For instance the command ReserveLocation allows you to reserve a location for a specific patient in advance of an activity that would use the location. 28. The PatientArrivals object has been greatly improved. For starters, the bugs have been worked out of the Hourly Arrivals table, but the arrivals will now repeat on a weekly basis. If distributions are used to define the number of patients arriving each hour of the week, the distributions will be resampled at the start of every day. 29. The scheduled arrivals (now called Appointments) can have variability about their scheduled arrival times. Because the arrivals are generated independent of each other, patients may arrive early or late to their appointed times, and consequently may overlap another patients appointment time. The appointment schedule may also be repeated if required. If the PCI value for a specific arrival is 0, the PCI classification index can now be assigned randomly from the empirical distribution defined on the Patient Classification table rather than explicitly defined by the user. The appointment times may be entered in days:hours:min format, or in terms of total simulated minutes as before. This now applies to all time entry fields! 30. Interarrival times may now be tied to a specific PCI number if desired, making more than one interarrival time distribution more useful. 31. The Patient Processing object can now have more than one patient in it at a time by simply specifying the Maximum Occupancy to a number greater than 1. 32. The status of the library (open/closed), the main view settings, any open windows, and all saved views are now saved with the model, and are loaded automatically when reopening the model. 33. The right-click popup menu for the main view window has been expanded to include more colors, standard views, and other display settings than before. 34. The object library window is placed on top of other windows when opened/closed in order to give you access to the library when other windows are in front of it. By the way, did you know you can right click on an object in the library and get a list of objects in the model of that type? Very useful in large models when you want to find

and edit a specific object. 35. The default directory for saving and opening files is a directory in the users personal Documents folder called FlexsimHC Projects. This is the default directory until changed by opening or saving a file to a different directory. 36. Ctrl-D is a shortcut key available in the main view for quickly duplicating a group of selected objects (red bounding box), or a single highlighted object (yellow bounding box). 37. New Excel import and export options available under Tools>Excel menu. 38. All tables in the application including those found on the Patient Arrivals object have right-click popup menu options for easily copying/pasting or importing/exporting the entire table or portions thereof. 39. Many more 3D shapes are included for locations, equipment and transports. 40. Staff Groups can now be assigned 3D shapes from a dropdown list. 41. Location objects show a colored band around their floor when being held by a patient. The color of the band matches the patients color. 42. Location objects show a red band around their floor when not available due to a shift schedule or experiment scenario. 43. Staff and patients now have more realistic travel patterns. They no longer stop at a node when using walking paths, but will offset travel all the way to their final process point when discernible. 44. When equipment and transports are dropped off, they are placed more intelligently. For instance, wheelchairs are placed in such a way as to hopefully not overlap with patients or beds when possible. When a resource (e.g. staff, equipment, transport) returns to its group, it is placed back in its original default position relative to the group. 45. Positioning of all patient shapes (e.g. man, woman, boy, girl, baby, baby in bassinet, and man in bed) have been improved for when the patient is placed in any of the standard locations. The user may manually position patients within locations as well. 46. Improvements have been made to the positioning of patients relative to transports, and staff relative to equipment or transports during travel. 47. You can now choose to display information above a patients head as they progress through the model. The information includes the patients name and a list of the activities that are currently in process for the patient. 48. Patient Queues can now be visualized represented with chairs, beds, a single file line, or open floor space. Single file lines now have a truer representation with patients shuffling forward after a patient at the front of the line leaves the queue. 49. An elevator object has been added to the library. Using an elevator in a model is extremely easy when using walking paths. Simply connect the elevator up to nodes in the walking path. As patients or staff cross a node connected to an elevator, it is determined whether or not the person(s) need to use the elevator based on the level of their destination compared to their current level. If the levels are different, a request to use the elevator is dispatched automatically. By default, the elevator will stop and pickup passengers who are along the way who are headed in the same direction the elevator is currently going so long as the elevator capacity has not been exceeded. Other control algorithms can be chosen by the user as well.

50. The text display options have been updated and expanded to match those available for dashboards and output files. 51. You now have the option to create nine separate output files rather than what was previously one file with the recorded data tagged with nine different codes. This should make it much easier for most users to deal with. The nine files are: PatientHistory, StateHistory_PatientQueuingLocations, StateHistory_PatientProcessingLocations, StateHistory_ItemQueuingLocations, StateHistory_ItemProcessingLocations, StateHistory_Staff, StateHistory_Equipment, StateHistory_Transorts and StateHistory_Totals. The delimiter for the column separator can now be one of four types (e.g. tab, semicolon, comma, space) for international compatibility. 52. Data is not written to the output files until after the user-defined warmup time has transpired. When the warmup time transpires, an event occurs which resets all statistical parameters as required. The times associated with data written to the output files is corrected to account for any user-defined start time. 53. Newly designed Experiment Manager interface is more user friendly and hopefully easier to use. One things for sure, it is much more powerful. 54. The user now has a very large list of experimentation variables to choose from. You may choose from predefined lists of location, resource, patient, and global variables; or create your own user-defined variables by selecting from a list of examples or defining one from scratch. A variable no longer needs to be associated with a single value on a single node in the tree, but can be an expression such as an existing algorithm that has been modified to contain an experiment variable you may have embedded in the code. It is now a simple thing to experiment with the number of staff members in a group, or the number of locations within an area. 55. The list of predefined performance measures has also grown substantially. You will be able to choose from a long list of PFMs associated with individual resources, groups of resources, locations, groups of locations, patient tracks, or global metrics. As with variables, the user may also define their own custom performance measures. 56. Performance measure reports have been enhanced to include more than just confidence intervals and standard deviations. Experimentation results now include histograms for replication frequency analysis, scatter plots for comparing correlation between variables, and nicely formatted html reports to display and compare the results and raw data for all performance measures and all scenarios! 57. More content 58. New animated gifs 59. Many new commands have been added and documented in the Command List.

Introduction

In order to get familiar with FlexSim Healthcare lets first talk about the interface you will be presented with when you first start the program. If this is your first time using FlexSim Healthcare, please go here to Interacting with FlexSim Healthcare to learn how to use the basic functionality of the program.

Section 1: The FlexSim Healthcare Toolbar

Section 1 is the FlexSim Healthcare Toolbar, which in addition to containing the familiar Windows style set of menu options also has buttons that allow quick access to some common FlexSim Healthcare interface elements. The buttons include creating a new model, opening a previously saved model or saving the current model. Flowitems: This button opens the Flowitem Bin, where you can edit the properties of objects that may move through your model. Floor Plan: This button helps the user import a floor plan drawing from a CAD program to be used as a background. Utilities: This button opens a window that contains useful model editing utilities. Output: This button let's you control the statistical output of the model. Dashboard: This button opens the dynamic dashboard display. The Dashboard is an area where a user may define and display custom statistical graphs for the currently running model. Experiment: This button will add an Experiment to you model, which will allow you to run iterations of your model with different variables and performance measures.

Section 2: The Simulation Control Panel


Section 2 is the simulation control panel. From this section of the interface you have quick access to the commands that control a model run. It is helpful to think of the simulation control panel as having two section of its own; the Buttons, and the speed control. Open/Close Library: This button opens the Library window. The Library window contains all the modeling objects you will use to build your models, such as Staff, Equipment and Locations. Simply Clcik the object type you wish to create and then click in the grid to place the object. Patient Tracks: This button opens the Patient Manager window. From this window you may add, remove, import or export patient track information. These patient tracks allow you to define patient flow and activities associated with different tracks.

Flowcharting: This button opens a simplified flow chart style view of your model. This view allows you to manage the possible flow choices patients may make as they move through your model. Click on Managing Object Connections for a more in depth look at this tool. Reset : This button resets the model and causes the The OnReset trigger to fire for each object in the model. Before running a model the initial events for the model and the initial states for the objects need to be reset. Therefore, before running a model from the beginning, you must press the Reset button first. Run : This button begins execution of the model events. The simulation clock will advance until the model is stopped, or there are no more events in the models event list. Stop : This button stops the model while it is running. The model is not reset and it can be started again from the exact point in time that it was stopped. Step : This button allows the user to skip model time ahead until the next scheduled model event. This allows users to step through the execution of a model event by event. When multiple events are scheduled to occur at the same time, there may be no visible changes in the model when this button is pressed. Stop Time : This button allows the user to adjust settings related to time settings in the model. Here you may define what time your model starts at, forexample a model that begins execution from midnight vs 8:00 AM. You may add a Warmup time to you model. After the model has run for this amount of time, the statistics are reset, but the model is not. You may add a Stop time to the model that will allow the model to run up to a certain time and then automatically stop. This is the same as pressing the Stop button as described above, and so the model may resume execution from this point by pressing the Run button. Run Speed: This slider defines the number of simulation time units that FlexSim Healthcare will try to calculate per second of real time. The actual result may fall short of this value if the model requires too much processing at each event. The speed value displays the value set by the slider, but it can also be edited directly by clicking the down arrow next to the speed value. Displays : This button shows the the Display options menu directly below it. Here you may add or remove graphic display objects from he model, or open the properties to an existing display. The Graphic Display gives you the option of displaying text or graphic feedback on the model during the course of it run.

Section 3: The Library


The library palette helps you create model resources. Click the resource you would like to add to your model and then click within a view window to create a new instance of that resource. The FlexSim Healthcare library of objects consists of modeling resources that will aid you in simulating whatever system you need. Within the library, there are different groups of resources; one for dealing with patients directly, and another for dealing with items that may be created during the course of a simulation. These items would be things such as lab specimens, paperwork etc.

Patient Arrivals: The first resource in the library is the Patient Arrivals object. This usually represents the start point for a model as it has control over how patients are introduced to the model, according to what interval and what tracks they will follow. Patient Exit: The Patient Exit resource is the typical end point to a model. Patients that have completed their track should be routed to the Patient Exit object and any data about the individual patient you may wish to capture should be done at this resource. Once patients enter the Exit object, they are considered destroyed. Patient Queuing: The Patient Queuing resource can be used anywhere in the model where you need to represent, for example, a waiting room for the patients. The Patient Queuing resource has three different visual styles; it can appear as a room with chairs, a row of beds or a line. Patient Processing: The Patient Processing resource is a very flexible object that can be used to represent many different process points for your patients. Whether you need to represent administrative activities, such patient registration, or a medical process such as a Physician consult, this is the resource you would use. Staff Group: The Staff Group resource is used to simulate the functions of your hospital staff. A single instance of the resource can be made to function as an Administrative, Nurse, Physician or Tech staff group. How these resources are used and when is a function of the patient activities in the track editor. Equipment Group: The Equipment Group resource allows you to simulate the function of physical equipment in your model. The resource can be made to appear as a crash cart, ventilator or others. Transport Group: The Transport Group resource is used to introduce transportation objects into your model. If you have a process that requires patients be transported via wheelchair, rather than walking under their own power, you could employ this object to that end. Elevator: The elevator object help simulate the situation where you need to move patients, staff or equipment to another "floor" of your facility. In order to use the elevator correctly you will need to make use of the Path object. Alternate Group: The Alternate group is a special object that helps Staff Groups coordinate with each other. If you had an activity that made use of staff groups such that one staff group was preferred but another could fill the staff requirement, you can make staff groups members of the Alternate Group. You can then use the Alternate Group in the activity and it will utilize one of the members. Item Arrivals: The Item Arrivals object is the first of the resources that do not deal with patients directly. Its function is to create items involved in processes centered around the other item-centric resources. Item Exit: The Item Exit object is the termination point for items in the model. When items are no longer needed by the simulation they should be routed to the Exit. Once items enter the Item Exit object, this is the last chance to poll any information from it before it is destroyed. Item Queuing: The Item Queuing allows you to store items wherever down stream objects may not be ready to receive yet. Item Processing: The Item Processing object is used for applying a process time to a given item. This allows you to simulate events such as a lab specimen having a test run it. Item Combining: The Item Combining object implements many features of the Item Processing object, but also adds the ability to join multiple items together. Item Separating: The Item Separating object also implements Processing features, adding the ability to separate or make copies of items. Item Conveying: The Item Conveying Allows you to cause flowitems to move, as if on a conveyor belt or through a pneumatic tube system from one location to another. Travel time across the Item Conveying object is a function of convey length and speed. Path: The Path object creates walking paths for patients and staff. See here for more information. Wall: The Wall object creates walls to give your model a more realistic feel. Wall creation works similar to Path creation. See the Paths Tutorial for more information

Section 4: The Model View


Section 4 is the model view window. The default model view to build a model is the Perspective view. The view windows allow you to observe and interact with your model. You also have an Orthographic View available to you if you prefer. To open the Orthographic View, right-click in the model view, and select Switch to Orthographic View.

Section 5: The Status Bar


Section 5 is the status bar. The status bar will show the current elapsed time, as minutes, in the model. Note that the a model's default unit of time is minutes, however the time scale is largely up to the user and may be easily modified. Highlighting an object in the model view will also cause information to be displayed about the object in the status bar. The object's name, area, as well as location rotation and size within the 3D space will be shown here.

Interacting With FlexSim Healthcare


Creating An Object
To create an object, select the object you want to create in the Library, then click in the model view where you want the object to be created. Example As objects are created, they will be given default names such as PatientArrivals#, where # is the number of objects of that type, created since the FlexSim Healthcare application was opened. You may rename the objects in your model during the editing process to be defined below.

Naming An Object
To name an object, double-click it to open its Properties window. Then edit its name at the top of the window and press Apply or OK.

Editing Objects
Moving Objects: To move an object around in the model, click on it with the left mouse button, and drag it to the position you want. You can also move the object up and down in the z direction using the mouse wheel, or by holding both the left and right mouse buttons down on the object, and drag the mouse forward and backward. Example Size and Rotation: To edit the object's size and rotation, select the main menu option Edit > Resize and Rotate Objects. When you click on the object, you should see three colored arrows along each axis of the object. To resize the object, left-click on the axis you want to resize on, and drag the mouse up or down. To edit the object's rotation, right-click on the arrow corresponding to the axis you want to rotate around, and drag the mouse forward or backward. Example Properties: All FlexSim Healthcare objects have a number of pages or tabs that present variables and information that the modeler can change based on the requirements of the model. See Object Library for details on each specific object. Changing 3d Shapes: To change an object's 3d shape, double-click on it to open its Properties window, and select the desired shape from the Shape drop-down list that is located near the top of each Properties window. Example

Destroying Objects: To destroy an object, highlight the object, and press the Delete key. View Navigation Basic Navigation: To move the model view point, click in an empty area of the view with the left mouse button, and drag the mouse around. To rotate the model view point, click in a blank area with the right mouse button and drag the mouse around. To zoom out or in, use the mouse wheel or hold both left and right mouse buttons down and drag the mouse.

User Authentication
FlexSim Healthcare User Authentication
Login Screen

When a user starts FlexSim Healthcare, they are presented with a simple login screen. Here they enter their personal user name and password. This is not related to the name of the license used to activate the software. This is a username assigned to each person that uses FlexSim Healthcare. There are three types of users: administrators, regular users and trial users.

Administrator
There is only one administrator account used by FlexSim Healthcare. The user name for this account is always admin. The administrator has the following permissions beyond a regular user: a. b. c. d. e. f. g. Create new users Delete users Change the activation status of existing users Change the location of the password file Open encrypted audit log files Save encrypted audit log files to plain text files Change the location of the audit log files

Regular User
A regular user can use FlexSim Healthcare without any restrictions to how the software works. There are no limits on the models that can be opened, the number of objects or tracks that can be created, etc. The only things that a regular user cannot do are the abilities specifically assigned to the administrator account.

Trial User
If a person wishes to try FlexSim Healthcare but does not have a user name or password, they can press Cancel at the login screen. This will start the software in a Trial mode that limits the features available as well as the number of tracks and activities that can be created.

Change Password GUI


To enhance security, a users password expires 180 days after it was set. After the password expires,

the user can still log in with it, but they will be prompted to change the password each time they do until it is changed. They will also be prompted to change their assword the first time they log in. The Change Password GUI is opened by selecting File|Login Options|Change Password from the main menu.

The Change Password GUI is very straight-forward. The user is required to enter their current password, and then the new password twice. If the old password is correct and the two instances of the new password match, then the password will be changed. If the user tries to change to a password that is not valid, then they will be shown a warning, and the password will not change. There are four requirements for a password to be considered valid: a. b. c. d. The password must be at least six characters long. The password must contain at least one number. The password must contain at least one lower-case letter. The password must contain at least one upper-case letter.

Due to the way that passwords are saved, if a user forgets their password, it cannot be recovered. Their account will have to be deleted and recreated by the administrator

Manage Users

The primary difference between the administrator user and a regular user is that the administrator can make changes to other user accounts. This is done through the Modify Users GUI, which is opened by selecting File|Login Options|Manage Users from the main menu. This GUI presents a list of the users that are currently available. Their names are shown along with

when they last changed their password and whether or not the account is active. There are also buttons to create a new user, delete an existing user or change the location of the password file.

New User
When the administrator wants to create a new user account, they press the New button. This allows them to define a new user name and give the new account a default password. Because this password will be known to both the administrator and the new user, the user will be prompted to change the password as soon as they log in for the first time.

Delete User
If an administrator no longer needs certain user accounts, they can be deleted in this GUI. When the administrator presses the Delete button they are shown a list of users that can be deleted (the admin user cannot be deleted). The user that they select will be deleted immediately. A deleted user cannot be restored, but it can be recreated (but the previous password will be lost).

User Status
Sometimes an administrator may want to make certain user names unavailable, but not deleted. This can be done by disabling the account. If the user clicks in the Status column of the table, they are shown a drop-down box that allows them to specify whether the user they clicked on is active or disabled. A disabled user cannot login and must be reactivated by the administrator.

Password File Location


The list of users and their passwords is stored in an encrypted file on the hard drive. The location of this file can be changed by an administrator. They would do this if they want to use a single user/password list for several different installations of FlexSim Healthcare (for example: a network installation). When FlexSim Healthcare is first installed, the password file is placed in the default location with just the administrator account available. The administrator (typically the person that installed FlexSim Healthcare) can then change the location of the file to a different directory. If the administrator chooses a new location for the password file, and there is already a password file in that location, the files from the two locations will be merged. Any users from the file in the old location that are not in file in the new location will be copied into the new location. If a user from the old file is also in the new file, the administrator will be prompted for which password to keep: the one from the old location or the one from the new location. The administrator account is not transferred. The admin accounts password will be the password that is stored in the new location.

Audit Log
Because of privacy concerns, FlexSim Healthcare tracks whenever a user logs in and what models they open. This information is stored in an encrypted file known as the audit log. A new audit log file is created every day. Each file keeps a list of all of the times that users attempt to log in or open a file. The audit log files can only be decrypted by the administrator. The audit log viewer is opened by selecting File|Login Options|Audit Log from the main menu.

Open Audit Log

The Open ( ) button allows the administrator to open an encrypted audit log for viewing. These log files cannot be read by any other users or programs. Each entry in the audit log shows the following information: a. The name of the FlexSim Healthcare user that performed the action (or <anonymous> if the user was unknown or was a trial user). b. The name of the Windows user that was logged in. c. The name of the computer where the action was performed. d. The action that was performed, such as LOG IN or OPEN MODEL. If the action performed is LOGIN CANCELLED then the user pressed the Cancel button on the login screen and started FlexSim Healthcare as a trial user. e. Other data that describes the action, such as the name of a model that was opened. f. The date and time that the action was performed.

Save Audit Log


The Save ( ) button is used to save the current audit log as a plain text file that can be read by any person or program. The original, encrypted file is not modified. Any actions that are later added to the encrypted audit log will not be in the text file unless it is reopened and resaved.

Audit File Location


Just as they can with the password file, the administrator can change the directory where the audit logs are saved. This may be a different directory on the local computer or it could be a ocation on a network somewhere. The Windows user that is using FlexSim Healthcare must have permissions to write to the location where the audit logs are to be stored.

Introduction Tutorial 1
In this simple tutorial model, we will introduce some basic simulation concepts and a scenario that will get you familiar with working within FlexSim Healthcare. As a rule of thumb it is a good idea when starting a new model to outline in some way the processes that your simulation will model, such as a simple flowchart or other aide. This gives the benefit of helping you narrow down the goal of the model, as well as help you organize what data from the real world system you need in order to define your models behavior. Once these preliminary steps are taken you can start going about building your model. Starting a model for the first time, you may feel unsure where to begin. With that in mind we offer the following simple 5 steps: 1. 2. 3. 4. 5. Create the Layout Define Possible Patient Flow via Flowcharting Create Patient Tracks Edit Settings for Applicable Objects and Resources Run and verify the model

Concepts You Will Learn


Creating, naming, and laying out a model. Creating a Patient Track. Directing patient flow (Flowcharting). Allocating staff members for certain activities. Changing basic properties of objects.

The Scenario
For the purposes of this tutorial we will use a fairly simple scenario. A minor care clinic with only four beds receives walk-in patients on a random basis around the clock. Upon entering, patients are required to register at the registration desk for 3 minutes. If the registration desk is busy, they must wait in a line for the desk to become available. After registration, patients go through a 4 minute triage process by a nurse. Following triage, the patients are escorted by the nurse to a bed where they will receive a 15 minute evaluation by the clinic physician. After the evaluation, patients are escorted out of the facility by the nurse.kn

Tutorial 1
Step 1: Create and Layout the Objects
In this step you simply want to choose what resources you will need to simulate your system and place them in the model. Place the objects so that they accurately represent your system. It is your choice to layout the model to scale. This choice is generally dictated by what kind of results you want to see from your model, such as whether or not you need highly accurate data from resource travel operations. Save your model as Tutorial1. Be sure to save after each step. Note: This step assumes that you know how to create objects, how to name them, how to move them, and how to change their 3d shape. If you do not, or would like a review, click here. Create a Patient Arrivals object. Create a Patient Queuing object. Change its shape to that of a Line. Create a Patient Processing object, change its Shape to Registration. Create a Patient Processing objects, change their Shape to Triage. Create four Patient Processing objects, keeping the default bed shape. Create a Staff Group object and change its name to NurseGroup1. Change any visual properties for the members as desired. Create a Staff Group object and change its name to PhysicianGroup1. Change any visual properties for the members as desired. Create a Patient Exit object. Place the objects as shown below. Close the library by pressing the button. . The names will not appear when

Note: I have placed the object names above the objects for your convenience using Displays you build the model.

Step 2: Define Possible Patient Flow With Flowcharting

You will define patient flow through the use of Object Connections. Object connections are an important part of making your model function properly. These connections allow patients to enter and exit the objects and move on to whatever destination your model may dictate. It may be helpful to think of these object connections as relationships between objects that patients use in order to move from location to location. The Flowcharting view of the model allows you to more easily manage and organize these relationships. It is recommend to make this your second step in model building because it can help organize your thoughts about how patients may move through your model. Click the Flowcharting button on the toolbar to access this view

In this view you will see all of the Areas in your model represented as colored rectangles. You may organize the arrangement of these representations however you like, as their positioning in this view does not change how they are arranged in the actual 3D model view. Positioning the cursor over the left hand side of the window will expose the options available for this view. Here you may chose to move the Area representations, connect them together or disconnect them. The connection modes for the cursor shown at the left (Move, Connect, Disconnect) may also be changed by right clicking in an open grid space. You may attach a name to a connection line as well as change it's color for increased organization and clarity. While in connect mode, establish connections to reflect where your patients will go for each of their travel activities by clicking on the origin Area and then clicking on the destination Area.

Notice that since patients need to use the waiting line area if the registration desk is not available there must be a connection to the WaitingLineArea from the PatientArrivals Area and from the WaitingLineArea to RegistrationArea. When Patients are walking unattended they will automatically try to find a Patient Queuing object to go to if the desired travel destination is unavailable, such as the registration desk in this case. If being escorted or transported, Patients will need to be explicitly told to use waiting rooms as part of their track. Connection lines may have a one-way arrow to indicate that travel between those objects is only allowed in the direction of the arrow head. For example Patients may not travel from the BedArea to the TriageArea. A bidirectional arrow may also be used to denote travel is permitted between two objects in either direction; this model does not make use of this type of connection.

Step 3: Create Patient Track


Tracks are the mechanism through which you will define patient movements and their activities in your model. For any patient assigned to a track, the track defines a list of activities that they may execute and what resources will be involved in those activities. To access the interface for creating and editing the patient tracks, click the button found on the FlexSim Healthcare Toolbar. This model will use a simple single track to get you acclimated to the idea of defining flow in this way. Many more complex possibilities than this example are possible. Models start with one track already created, but with no activities, so all we need to do is edit the existing track.

First Activity - Arrival


When activities are created, you may choose a Milestone for that activity. Milestones have a couple useful purposes. First, they are used to generate charts and statistics so that you can more easily measure the results of your model. Second, they are used for your convenience in naming activities. There is a small list of built-in milestones you can choose from, but you can also type whatever you like into the Milestone Marker field to customize the model to your situation. When you first chose a Milestone, it will change the activity name to match, if you haven't already named your activity. In this model, we will use the built-in milestones to name our activities, but it should be understood that both activity names and milestones names are customizable, and a custom milestone name will still generate the same charts and statistics with the name you define. Note: Depending on which Activity Type you choose, the applicable options in the window will become available. For an activity like Patient Travels Unattended, most of the options in the window become unavailable (grayed) and you cannot edit them. Note: When you add your first activity to your track, it will have given the name "10_". This "10" used in the name is included as the numeric activity ID, and is a required part of the activity name. Every track you add will have a number followed by an underscore at the beginning. On the Activities tab, click the Add button above the Activity List column. This will add an activity with the name 10_ which you can edit later. Choose Arrival from the Milestone list. This will change the name of your activity to 10_Arrival. From the Activity Type list, choose Patient Travels Unattended. From the Patient Destination list, choose RegistrationArea. This will tell the patient, when he enters the model, to go unattended to the registration area. Don't close the Track Editor yet, but you may click Apply if you wish to save changes as you go.

Second Activity - Registration


The next activity we are going to add is registration. The patient will come in, register, then wait for the next available nurse in order to begin triage. For this activity, we will need to define a process time of 3. Click the Add button to add an activity to this track. From the Milestone list, choose Registration. From the ActivityType list, choose Process. Notice that this ActivityType has more options available than our previous activity, such as Process Time, and Staffing Requirement. In the Process Time field, enter 3. No Staff will be assigned to this activity.

Third Activity - Triage


After the patient registers, he needs to be triaged. In this activity, we will have a nurse come pick up the patient, escort him to a triage area, and triage him, which will take 4 Minutes. Click the Add button to add an activity to this track. From the Milestone list, select Triage. From the ActivityType list, select Escort Patient > Process. In addition to the options available from the Process activity type, you may also specify a Patient Destination similar to our first activity. From the Patient Destination, select TriageArea.

In the Process Time field, enter 4. Under Staffing Requirement, click the Add button to add a Staff Group to this process. Select NurseGroup1 from the first dropdown menu (Note: if you gave your nurse group a different name, it will appear in the list instead). In the second dropdown chose Any Member.

Fourth Activity - Transfer to Treatment Room


After being triaged, the patient will be escorted and placed in a bed. See if you can create this activity on your own. Add the activity, set the milestone, set the activity type, set the process location, set the process time, set the next area, and allocate a nurse to do the process. After finishing, check yourself with the steps below. Click the Add button to add an activity to this track. Set the Milestone to Bed Placement. From the ActivityType list, select Escort Patient > Process. From the Patient Destination list, select BedArea. Leave the Process Time field blank. The time it takes for the patient to be moved to the bed will be accounted for naturally, as a function of the walking speed of the Nurse/Patient and how far a distance they need to travel. The process time for this activity type is only used if you want to associate a delay time with the Selected Staff and the Patient after they arrive at their destination. Under Staffing Requirement, click the Add button to add a Staff Group to this process. In the first dropdown, use First Used from Group and in the second select NurseGroup1. This will ensure that the same nurse involved in Triage will then take the patient to his bed.

Fifth Activity - MD Exam


After being placed in a bed, the patient will receive treatment from a Physician. See if you can create this activity on your own as well. Check yourself with the steps below when you are done Click the Add button to add an activity to this track. From the Milestone list, select MD Exam. From the ActivityType list, select Process. In the Process Time field, enter 15. Under Staffing Requirement, click the Add button to add a Staff Group to this process. Select PhysicianGroup1, from the first dropdown menu and Any Member from the second. From the Process Location list, select Patient's Location.

Sixth Activity - Exit

Finally, the patient has been seen and treated. The patient may now leave the facility, under the supervision of a nurse. Click the Add button to add an activity to this track. Use the Milestone Departure. From the ActivityType list, select Escort Patient > Process. From the Patient Destination list, select PatientExitArea. Under Staffing Requirement click the Add button to add a Staff Group to this process. Select NurseGroup1 from the first dropdown menu and Any Member from the second. Click OK to apply the changes and close the Track Editor at once.

Note: it is not necessary for every activity to have a milestone associated with it. In fact, you will generally only want to assign milestones to significant activities for whom you wish to gather statistical data. This is especially true for large models that you may build with many activities; the less significant activities' milestones can begin to clutter your outputs.

Step 4: Edit Applicable Resources


In this step you will need to open the Properties window for any resource whose behavior or appearance you wish to change. This is the step where you may want to add more members to a staff or equipment group, alter the way patients are introduced to the model, or change what objects will look like.

PatientArrivals
While we are not going to change any settings on the PatientArrivals for this model, a basic knowledge of a few things will be helpful. Double-click on the PatientArrivals to open its Properties window. Click the Interarrival Times tab. This is where you can change the distribution of how often a patient will enter the model. We will leave it at the default value, which is an exponential distribution with a mean of 20. You can also define arrivals patterns on the table of the Hourly Arrivals tab, Appointments tab and the Custom Arrivals tab.. If you want/need more information on the PatientArrivals object, click here. Click OK to close the Properties window.

Change the Number of Doctors in PhysicianGroup1


Double-click on PhysicianGroup1 to open its Properties window. Under Staff Members column at left, click the Add Staff button. When adding staff, the newly created member will copy the visual properties of the first member in the list; such as gender, shirt/pants color and so on. Click the OK button to apply the changes and close the Properties window.

Step 5: Run the Model


Once you have finished defining how the model will run, you can then run the model. First, click button in the toolbar to reset the model, and finally click to see it execute. During this step you can verify that the tracks and resources are doing what you intended. When you are finished, save your model as Tutorial1.

Introduction Tutorial 2
In this simple tutorial model, we will build upon the previous tutorial and a few slightly more advanced concepts into the model. Here we will learn how to incorporate real time model outputs via the Dashboard feature, and see how we can work with equipment and transport groups. We will also introduce the Decision Point activity type that can facilitate random choices within the patient track.

Concepts You Will Learn


Creating Dashboards Modifying a Patient Track. Assigning Transportation and Equipment resources to activities The Decision Point activity type

The Scenario
We will use Tutorial 1 as the jump off point for Tutorial 2 and modify it slightly with some changes to the Patient Track. Activities will remain the same up to the MD Exam Activity, after which we will add a decision point activity. That will transport a low percentage of patients via wheelchair to a separate exam room for an activity that requires staff to be involved with the patient with a Computer on Wheels equipment. Patients will be escorted out of the model after this activity, or if they did not need this additional activity..

Tutorial 2
We will begin this model by opening your Tutorial1 model made previously and saving it as Tutorial2

Step 1: Create Additional Objects


In this step we will create the objects we need to facilitate the new activities we're going to add later in step 3. We will add a new exam room, an equipment group in the form of a Computer on Wheels (or CoW ) and a transportation group in the form of a wheelchair. Open the object Library Double-Click on Bed4 in the Model and set it's Shape to Exam Room. You may notice that this will automatically change the Name and Area of the object, which is desired for this model. You may find it useful to rotate this object 90 degrees and move it off to the side of the rest of the beds, in order to improve the visuals of the model. Create an Equipment Group, and set its member shape to C O W. Create a Transport Group. Place the Objects as shown below:

Step 2: Modify Flowcharting


Go into the Flowcharting for the model and add a connection from the BedArea to the newly created ExamRoomArea. Also create a connection from the ExamRoomArea to the PatientExitArea

Step 3: Modify the Patient Track


For this step, we will edit the patient track that we made in Tutorial1. First, we will add an activity that will take place after the initial treatment with the Physician that will be a Decision Point activity type. Here the track will decide if the patient is required to go to the new exam room. To add an activity between two other activities, highlight the beginning activity MD Exam) and click Add. This will insert a new activity after the highlighted activity, and give it an Activity ID the number halfway (or closest) between it and the next activity. In this example, our first new activity will be given the ID of 55. In total we will be adding 3 new activities; the decision point, the activity that takes the patient to the new exam room, and the new procedure with the C O W unit. Note: When inserting activities as we will do here Predecessor lists will need to be updated to ensure that only the activities we intend to start, start. In this case the Predecessor for the Departure activity will need to be modified.

Activity 55 - Decision Point


Decision Point Activities happen in zero time and are used to allow a choice between multiple activities that could start after the decision point. The unique property of the decision point activity is the Next Activity dropdown menu where you can chose an option that defines how, and what activates may begin next. A Decision Point activity should not be used as a Predecessor for any activities in the track, as any activity that the decision point will chose will be caused to start immediately upon the choice being made. Instead, any activity that is to start if only if the decision point choses it should uncheck the checkbox next to the Predecessor field. This will disable predecessors for this activity so it cannot start except when explicitly told to start by the decision point. Open the Track Manager, go to the Activities tab and highlight activity 50, MD Exam. Change the new Activitys name to 55_Decision. For this activity there's no need to use a Milestone. In the Activity Type List, chose Decision Point. In the Next Activity dropdown menu, chose the option called Based on Probability. This option allows you to type an expression in the blue text area made up of Percentages and Activity ID pairs separated by comas. For now leave the expression field blank, we will come back to it later.

Activity 100 - Move to Exam Room


This activity will transport our patient to the new exam room we created in Step 1. Notice that the ID will be different than the numbering scheme used for the earlier activities. This is often good practice so you can easily tell that there is something different about this activity because of it's numbering system. While Highlighting activity 55, click the Add button above the activity list. In the Milestone field type Transport to Exam . Change the Activity ID to 100. Disable predecessors for this activity by unchecking the Predecessor checkbox. Change the Activity Type to Transport Patient > Process. Set Patient Destination to ExamRoomArea. Add Staff, and chose First Used From Group from the first dropdown and NurseGroup1 from the second. Click the Add button under the Transportation Requirement and chose the Wheelchair1 group from the dropdown. Check the Return checkbox in Equipment Requirement.

Activity 110 - New Exam


This activity will require the nurse that escorted our patient to go get the C O W unit and bring it to the patient, where they will both be involved with the patient for 8 minutes.

While Highlighting activity 100, click the Add button above the activity list. In the Milestone field type New Exam . Change the Activity ID to 110. Set the Predecessors to 100. Change the Activity Type to Move Equipment > Process. In the Process time field, type 8 Add Staff, and chose First Used From Group from the first dropdown and NurseGroup1 from the second. Click the Add button under the Equipment Requirement and chose the COW1 group from the dropdown. Check the Return checkbox in Equipment Requirement.

Activity 55 - Decision Point pt. 2


Now go back to activity 55 and in the Next Activity Field: In the Next Activity dropdown menu, chose the option called Based on Probability. Set the number of activities this decision point can chose to 2. Type the following expression {70, 60, 30, 100} into the blue text between the {}. The commas are required but the white space is optional. This expression tells the Decision Point Activity that 70% of the time to chose activity 60, and 30% of the time to chose activity 100. Therefore, 70% of the patients will leave via activity 60_Departure without needing the extra exam. Note: These percentages must add up to 100% in order for the option to work properly.

Activity 60 - Departure
Because of the new activities we need to adjust activity 60's predecessors to make sure that it only executes under one of these two conditions: 1. Activity 55 choses it as its Next Activity 2. Activity 110 completed. Therefore, do the following: Highlight Activity 60_Departure in the list. Change the Predecessor to 110

Step 4: Add Dashboard Charts and Graphs


Dashboards are a way of creating dynamic charts and graphs that output important statistical information for your patients and objects. Click on the Dashboard button in the toolbar: Click on the Pie Chart button: Click on the Line Graph button: and chose Patient States from the dropdown. and Chose the Patient Census graph from the dropdown.

These graphs will update as the model runs. In the case of the Patient States graph, data collects when patients leave the model and will update then.

Step 5: Run the Model

Introduction Tutorial 3
In this Tutorial we will build a very simple model as far as the patient is concerned, and will focus on a different set of objects. These are the item objects, which do not interact with patients directly but can execute some important functions on behalf of a patient. You will see that the purpose of the item objects is to handle the flow and processing of items, which represent some kind of physical entity, such as paper work or lab samples.

Concepts You Will Learn


Working with Item Objects Constructing a Track to take item objects into account

The Scenario
The model you will build will stand alone from the previous two tutorials. It will consist of a very simple scenario where a patients arrive directly to a patient processing object, patients will have a lab sample drawn from them as part of their track. The sample will be divided into 3 parts, representing 3 separate tests that need to be performed. When all 3 tests are complete, the results will be reviewed with staff, after which the patient will be allowed to leave.

Tutorial 3
There are essentially two ways to simulate lab events in FlexSim Healthcare; abstract and non-abstract. Sometimes in a model you may find it preferable to approaching the simulation of a lab process as an abstract event within the patient track. You would usually take the abstract approach if the waiting time, travel time, staffing or other constraints on the lab sample is immaterial to the results of your model. In this tutorial we will take a focused look at using Item-class objects to model the scenario of taking a lab sample and processing it according to its own logic. Here we will take the non-abstract approach where the patient track doest know how long the process of the sample will take and sample is allowed to follow its own set of logic before syncing back up with the patient .

Step 1: Create Model Layout


Open the Library. Create a Patient Arrivals object. Create a Patient Exit object. Create a Patient Processing object. Create a Staff Group object. Create an Item Queuing object, change its shape to a table and name it LabQueuing. Create an Item Separating object, and name it LabSeparation. Create 3 Item Processing objects; change their names LabProcessing1, LabProcessing2, LabProcessing3. Create an Item Combining object and name it LabCombining Create an Item Exit object. Close the Library. Place the objects as shown below:

Step 2: Flowcharting
Notice that our Item-class objects do not appear in the Flowcharting view. Connections that dictate flow for Item-class objects are handled on a per-object basis from their properties , and will covered in Step 4.

Step 3: Create Track


Activity 10 - Arrival
On the Activities tab, click the Add button above the Activity List column. Choose Arrival from the Milestone list. From the Activity Type list, choose Patient Travels Unattended. From the Patient Destination list, choose BedArea

Activity 20 - Draw Sample


Click the Add button From the Milestone list, select Labs. From the ActivityType list, select Process > Send Item. From the Item Destination, select LabQueuing. In the Process Time field, enter 5. Add Staff to the Staffing Requirement, and chose StaffGroup1 from the first dropdown and Any Member from the second. Take note of the Assigned Activity ID Field but leave it blank for now. You will come back to it later. The purpose of this field is to allow the Item processes to "sync" back with the patient that created the item.

Activity 30 - Review Results


Click the Add button above the activity list. Set the Activity Type dropdown menu to Process Type ReviewResults in the Milestone Field . Disable Predecessors for this activity by unchecking the checkbox next to the Predecessor field. (This is very similar to what you would have done in Tutorial2 with regards to the activities selected by the Decision Point activity). Add Staff, and chose First Used From Group from the first dropdown and StaffGroup1 from the second.

Activity 40 - Departure
Click the Add button to add an activity to this track. Use the Milestone Departure. From the ActivityType list, select Patient Travels Unattended. From the Patient Destination list, select PatientExitArea. Go back to Activity 20, and in the Assigned Activity ID type 30. Click OK to apply the changes.

Step 4: Setting up the Lab Objects


Lab Queuing
The LabQueuing object will serve as the place where lab sample will be sent to await processing. Double click the object to bring up its properties. The only changes to the object's properties we need to make are to the Connections tab, which allows us to determine where samples will be sent from this point. Read more about the Item Queuing object here. Connections Click Connections tab Click the Output Button on the top right of the window Highlight the LabSeparating object in the left hand list. This list shows all other Item-class objects currently in the model. Click the Left to Right Push button between the two lists. This will make the ItemSeparating object an outbound destination from the Queuing object. The LabQueuing object does not require any inbound connections in this example.

Lab Separating
The LabSeparating object is able to take an item and make copies of it. It can be given a process time to simulate the time it takes to make copies, an expression to dictate how many copies to make, and manage its connections like the Item Queuing object. In This scenario the Item

Separating object will give us a way to turn one sample in many, as in the case of needing to do multiple tests on a single lab specimen. Read more about Item Separating here. Process Settings Click the Process time dropdown menu, and in the blue text type 5.

Separation Settings Click the Separator Tab Click the Split button. Click the Split or Unpack Quantity dropdown menu, and choose By Expression from the list Type 3 into the blue text.

Connections Click Connections tab Click the Output Button on the top right of the window Highlight all 3 the LabProcessing objects in the left hand list. Click the Left to Right Push button between the two lists.

Lab Processing
The LabProcessing objects will serve as the place where the actual tests on our Patients sample will be done. They have the ability to process an item for a specified amount of time. They may process automatically, or while requesting staff. To read more about the Item Processing object read here. Process Settings Click the Process time dropdown menu, and in the blue text type 7.

Connections Click Connections tab Click the Output Button on the top right of the window Highlight the LabCombining object in the left hand list. Click the Left to Right Push button between the two lists.

Lab Combining
The Item Combining object can serve as a compliment to the Item Separating object. Where the Separating object can take Items apart, the Combining object can put them back together. The Item Combining object has a Process time just like the Separating and Processing objects do. The Combining object can combine Items in two ways, Joining and Packing. Joining involves taking multiple Items and turning them into one Item. Packing is taking multiple Items and putting them inside a container, such as placing boxes inside of a larger box. You may wish to read more about the Item Combining objects functions here. Process Settings Click the Process time dropdown menu, and in the blue text type 0. this means the combination process will happen instantly. Combine Settings On the Combine Mode dropdown menu, chose Join. Take note of the Components list table. Though we don't need to make any changes to these settings in this tutorial, it would be good to read what it does here.

Connections Click Connections tab Click the Output Button on the top right of the window Highlight the LabExit object in the left hand list.

Click the Left to Right Push button

between the two lists.

Lab Exit
The purpose of the LabExit is to take all the Items out of the model when they are done with their process, much like the Patient Exit object. In our example we will use this object to signify the end of the Lab Processing, and cause it to start the review results activity in the Patient track. Thus, we synchronize the Track process with the Item processing. Read more about the Item Exit here. The section dealing with Triggers would be especially helpful. OnEntry Trigger In simple terms a trigger is provided as away to execute custom behaviors when key events in your mode happen. The OnEntry trigger will fire whenever an Item arrives to the object. We will use this event to cause the next activity for our patient to take place. Click the button to show a list of common modeling logic for this trigger. Choose Start an Activity. Take note of the editable blue text options but do not change them

Step 5: Run the Model

Note: In this example the Patient has no activities to execute while the Items are in process.

Tutorials 4 and 5 Introduction


Introduction
The purpose of these small tutorials is to help you get very familiar with Paths. We will build two small models that incorporate paths. For additional practice see if you can incorporate Paths into Tutorial2. Walking paths are an aid to your model that allow you to designate valid paths that Patients, Staff and Transport resources will use when executing a travel activity. With no Paths available, these mobile resources will take the shortest distance between two points or objects. Adding paths adds extra, more realistic behavior to your model.

Concepts You Will Learn


Creating and Editing Paths Connecting Objects to Paths Disconnecting Objects from Paths Creating Paths that Branch Editing Objects to Use Paths You may find it valuable to read Interacting with Paths before proceeding to tutorials 4 and 5.

Interacting with Paths


Laying Out a Path
Note: Due to changes in the interface from version 2.01 and on, paths are now created by clicking the button in the Library. The technique of creating, editing, and using the paths has not changed. Paths are created the same way other objects in FlexSim Healthcare are created. To create a path, select the Path object in the library, then click inside the Model View. Every time you click in the model view, a node will be created and it will be connected to the last node you created. To stop creating nodes, click the right mouse button. After clicking the right mouse button, you will still be in path creation mode, but the next node you create will not be connected to the previous node. Example

Connecting Objects to a Path


There are two methods for connecting objects to the path. Double click the object to bring up its properties, and check the checkbox "Connect to Path". The Object will then connect itself to the node closest to its upper left hand corner Alternatively, Highlight the node you wish to be connected to the object, then click the object. A green connection line will appear if the connectionw as created properly. Any object that will be traveled to from a path must be connected to the path. Example

Disconnecting Objects from a Path


To disconnect an object from a path, repeat the process used to connect the object to the path. Highlight the node, then click the object, or use the Properties window. The green connection line will disappear. Example

Creating a Branch in a Path


To create a branch in the path, highlight the node you wish to branch from, and click where you want to create the new node. Example

Editing Staff to Use Paths


To connect staff to the path, double-click on the Staff Group object, and in the Properties window check the Connect to Path Network checkbox. This will connect the Staff Group object to the nearest node. Example

Changing the Appearance of Paths


To change the appearance of paths in your model, double click a node to access its properties and click the Toggle Display Mode button. You may also use a keyboard shortcut to cycle through the models; press and hold the X key, then left-click any node. There are six modes to choose from, and you can find out which you like best by experimenting. These different display modes are demonstrated below. Example

Tutorial 4
Introduction
In this tutorial, You will create a Patient Arrivals object and a Patient Exit object, and connect them with a path. This model will teach you how to create a simple path and how to connect objects to a path.

Step 1: Create and Layout the Objects


Open the Library. Create a Patient Arrivals object and a Patient Exit object. Create a StaffGroup. Place them as shown below. Close the Library.

Step 2: Create the Path


Select the Path object in the Library. Each time you click in the model, a node will be created, and will be connected to the last node, creating a path. Create a path as shown below with 5 nodes, making somewhat of a "W" shape.

Step 3: Connect the Objects to the Path


In order for our patients and staff to be able to use a path, it needs to be connected to every object that they will have to travel to. There are two methods for connecting objects to a Path; You may double click the object to get it's properties and check the "Connect to Path" box, or while the path creation mode is active on the mouse cursor, click the node and then the object. You will see a green line appear between the object and its node In the first method, the node closest to the upper left hand corner of the 3D object will be connected to the object Connect the Patient Arrivals object and the Patient Exit object to the path.

Connect the StaffGroup to the Path

Step 4: Create the Patient Track


In this model, our track will only have one activity: Arrival. The patient will enter, travel along the path, and exit. button, then by clicking the Edit Track button. Click the Add button to add an activity to the track. From the Milestone Marker list, choose Arrival. From the ActivityType list, choose Escort Patient > Process. From the Patient Destination list, choose PatientExitArea. Click the Add Button under Staff Requirment. Select the Staff Group under the first dropdown and Any Member from the Second. Click OK to apply the changes and close the Track Editor.

Step 5: Connect Objects


Open the Flowcharting tool to create the necessary object connection to allow patients to move through the model.

Step 6: Reset and Run the model


Reset and Run the model. Watch to make sure that the patient travels along the paths to get to the exit

Tutorial 5
Introduction
In this tutorial, we will create a model where patients enter through a Patient Arrivals object, register at a Patient Processing object, then leave the model. The path we will use will have a branch in it to the registration desk.

Step 1: Create and Layout the Objects


In this step, we will create the four objects that we will use in this model. Create a Patient Arrivals object and a Patient Exit object. For the Patient Arrivals object set the Interarrival Time on its Interarrival tab to be exponential(0,5,1). This will make patients arrive more frequently. Create a Patient Queuing object. Create a Patient Processing object and change its Shape to Registration. Place them as shown below.

Step 2: Update Flowcharting


In this step, we will use the Flowcharting tool to establish object connections so our patients can travel through the model. Note that Patients will only travel to the waiting room if two conditions are true; The registration desk has to be unoccupied by another patient and the patient must be walking unatttended. When the Registration desk becomes available, the patient will be allowed to leave the waiting room and travel to Registration. This behavior is handled automatically only when traveling unattended.

Step 3: Create the Path


In this step we will create a path that goes from the Patient Arrivals object to the Patient Exit object with three nodes, then from the middle node, we will branch up to the Patient Processing object. Create a path with three nodes as shown below. Right-click when finished to stop creating the path. Highlight the middle node, then create a node near the Patient Processing object, as shown below.

Step 4: Connect the Objects to the Path


In this step, we will connect all four objects to the path. Remember that in order for a patient or a Staff Group to reach an object, it must be connected to the path. While in Path Creation mode, highlight the node near the Patient Arrivals object, then click the Patient Arrivals object to connect it to the path. A blue connection will appear. Repeat the above step with the other three objects using the node that is closest to each to connect it, as shown below.

Step 5: Create the Patient Track


In this step, we will create the simple patient track. This track will only contain 3 activities: Arrival, Registration, and Departure. We will not use any staff for the registration since this tutorial is just to familiarize yourself with paths.

Activity 10 - Arrival
button on the main toolbar. Click the Add button to add an activity to the track. From the Milestone Marker list, select Arrival. From the ActivityType list, select Patient Travels Unattended. From the Patient Destination list, select <RegistrationArea.

Activity 20 - Registration
Click the Add button to add an activity to the track. From the Milestone Marker list, select Registration. From the ActivityType list, select Process. Enter 10 in Process Time.

Activity 30 - Discharge
Click the Add button to add an activity to the track. From the Milestone Marker list, select Discharge. From the ActivityType list, select Patient Travels Unattended. From the Patient Destination list, select PatientExitArea.

Step 6: Reset and Run the Model


Reset and Run the model. Make sure that the patients travel along the path to the Registration area, and then to the PatientExitArea.

Patients
1. Patients 2. Track Manager 3. Track Manager Advanced Functions

Patients
Patients in FlexSim Healthcare are represented by individual objects, who are agents within the model. These objects, as soon as they are created by the Patient Arrivals object begin making requests on location objects and resources, in order to service their needs, defined by the Track Manager. Tracks are discussed in detail in the next section and the tutorials.

The Patient
The Patient as an object gives the user access to data that the patient gathers about itself and what it is doing in the model. Patient data is organized into three tabs that you may view by double clicking the patient. Here you will see the Stats tab, where data about what the patient is doing is stored, the Visuals tab that allows you to change what the patient looks like and the Labels tab where patient characteristics are stored. The labels tab also allows for the creation of custom data defined by users. The title bar on the patient GUI displays the current location of the patient within the model, as well showing you the patient's name. The name is automatically constructed by taking the name of the track that the patient belongs to and a unique identifier that tells you what number patient this is. In the below example the patient is identified as belonging to Track1 and has the numeric identifier 1, meaning it is the first created patient from this track.

Stats

The stats tab is split into three sub-tabs. The General tab gives a quick look at some basic information about the patient right now. Here you will find the current patient state, the patients current location within the model, the Patients Length of Stay statistic, what staffing and procedural costs the patient has accrued, the patients distance traveled and what ongoing activities the patient is currently involved with. This information is a snap shot of the patient at this moment of time, and it will be updated in real time as the model progresses. As shown abovem each Patient will keep track of it's own Length of Stay (LOS) statisitc. By default, Length of Stay is defined as the period of time from when the patieint first is created by the model until the time that the Patient is released to a Patient Exit object. The LOS statitic for all Patients can be reported through Dashboards and the output files, as well as be used as a Perfrmance Measure from within the Experimenter. The Procedural and Staffing Costs statistics are broken up into costs based on time spent with staff and costs based on activities completed, both statistics are updated at the end of the each activity. Staffing Costs are based on the Pay Rate field on the Staff Group Object's properties. Therefore what ever amount of time the staff is engaged with the Patient directly impacts the Staffing Costs output. Procedural Costs are generated based on the Fixed Cost and the Variable Cost Rate fields found on the activity properties from the Track Manager. At the end of an activity, the fixed cost value is added with the total variable value, based on how long the activity took to complete, and updated on the Patient.

The Patient States tab shows a report of the patients states to this point, displayed as a pie chart. The values displayed are a percentage of total time in the model. Patient States are defined as follows: STAT_ReceivingDirectCare: The process time for activities where the user has identified the process location as "patient's location", plus the process time associated with processes occuring in conjunction with an escort or transport activity. STAT_ReceivingIndirectCare: The process time for activities not occuring at "patient's

location". The patient is put in this state from the time the staff and/or equipment are allocated (if applicable) to the time the process time has finished. This also acounts for time when the patient is amidst a Process activity where no staff is assigned. On rare occurance, it is also the default state the patient is put into when an activity finishes and there are no other activities ready to begin because of predecessors, start times or start conditions. STAT_InTransit: The time a patient is walking, being escorted, or being transported to the area designated in the "Patient's Destination" dropdown. STAT_WaitingForRoom: The time a patient waits for an available location within the area designated in the "Patient's Destination" dropdown.. STAT_WaitingForStaff: The time patient waits for staff to be allocated to a process at the patient's location, or for staff to bring equipment/transports to the patient's location, or for staff to come pick up the patient to be escorted/transported. STAT_WaitingForEquipment: The time spent waiting for equipment to be allocated at the start of a Move Equipment > Process activity assuming the subsequent process will occur at the patient's location. The patient is also put into this state when waiting for equipment as part of an Allocate activity. STAT_WaitingForTransport: The time spent waiting for a transport to be allocated at the start of Transport Patient > Process or a Move Transport > Process activity assuming the subsequent process will occur at the patient's location. The patient is also put into this state when waiting for transports as part of an Allocate activity. STAT_WaitingForSupplies: the patient will only enter this state if the modeler uses the setobjectstate() command to specifically set the state of the patient to this state. There can never be more than one patient transfer activity underway at one time, but there could be multiple process activities ongoing at the same time; in which case it will be the last state change that takes precedence. For example, let's assume a patient has two separate activities (e.g. A and B) that can occur at the same time, and they both require staff, and they both are to occur at the patient's location. Let's say A started first and the patient was first put into a WaitingForStaff state waiting for staff to be allocated, then put into a ReceivingAttention state. Now when B starts, the patient's state will be changed to WaitingForStaff until the staff associated with activity B are allocated, then the patient will be put into a ReceivingAttention state again. When A or B finishes, the patient will remain in the ReceivingAttention state associated with the activity that has not finished yet. A patient will remain in its WaitingForRoom state even if redirected to walk to a PatientQueuing object and wait.

The Patient Milestones tab shows a bar graph that shows the time it took the patient to complete the milestones defined by the activities of a patient track.

Visuals

The Visuals tab gives you control over the appearance of this particular patient. You may change the 3D shape, change the color, speed as well as the spatial attributes of the patient. Note that these settings apply to this unique patient only. Visual settings for all patients should be set via

the Visuals tab on the Track Manager.

Labels

The Labels tab stores various information about the patient. Some labels are included automatically such as the PatientID, PCI, Track, Acuity, Appointment Time (only used if the patient arrived via an appointment schedule) and Arrival Time (also used by the appointment table arrival style). Users my also include their own labels to store custom information that may be used for various modeling needs. The last two labels in the list above are examples of custom labels. You may access values stored in labels via picklist options or via code with the appropriate commands.

Track Manager
The Track Manager allows you to create and manage patient tracks. You may also change the shape and color of patients associated with different tracks will appear in the model and import and export track information for use in other FlexSim Health Care Models. There is also an option to rename the currently selected track at the bottom of the window.

Tracks
In simple terms a track is an easy way to break patients into different types that define possible pathways those patients may take in the course of a model. It's important to note that the flexibility accorded to patients within a track is completely up to the modeler. They can be as flexible or as rigid as your model requires. You may choose to make tracks such that each track defines a sequential list of activities or tracks that define multiple different pathways that can be chosen by an individual patient at runtime. A track is a list of all possible activities that might be conducted on, or in behalf of, a given patient type. The activities can occur at any time, and multiple activities can occur simultaneously. It is possible that not all activities defined for a given track will be carried out for every patient using the track in the model. Activities are spawned based on user-defined criteria such as a list of predecessor activities, an earliest start time and/or repeat interval, a conditional statement that is checked at runtime, or the activity may be explicitly called as specific events occur in the model. Once an activity is spawned, requests are sent out for a location and any required resources. Resources are things such as staff, equipment, transports and material. The activity will proceed as the resources become available and get allocated to the patient for the specific activity. Resource requests are handled on a first-in-first-out (FIFO) basis within the same priority level unless an activity has been marked as a preempting activity, in which case resources will be preempted away from other tasks of lower priority. To allow for ultimate flexibility, any of the parameters associated with an activity such as process location, process time, staff required, earliest start time, etc. can be modified during runtime either with triggers or by simply using an expression to define the parameter initially. Some of the things to consider when deciding on what tracks to include in a model: 1. What are the current ways you classify or categorize your patients, and is there data already organized according to various patient classifications?

2. How would you like to have the results reported? Although it is possible to organize and classify the simulation results according to any user-defined patient attribute from the Output files that are created during a run, there are several predefined dashboards that are already presented on a "per track" basis. 3. If the decision for which activities must be completed for a given patient is based on the state of the model at the time the decision needs to be made, then you should not split the alternative activities into separate tracks. Instead, the alternative set of activities should be included as separate processes within the same track that are chosen based on conditional statements selected/written in fields such as the "Activity Start Condition", Decision Point activity type or "Next Activity Chooser" found in the Advanced Functions editor for an activity step where the decision needs to be made.

The Track tab allows you to create, edit and reorder the ranks of existing tracks in the list. The other tabs will display information only relevant to the selected track in the list. If you change the selected track, the information on the other tabs will automatically change. You can also see a preview of the patient that will be created by the highlighted track in the view panel to the right of the list. This is a full 3D view that you can manipulate similarly to the main view window.

Activities

Patient tracks are the mechanism through which you will define patient movements and activities in your simulation models. For any patient assigned to a track, the track defines a list of activities that they may execute and what resources will be involved in those activities. The interface for creating and editing patient tracks is available from the Patient button in the FlexSim Healthcare toolbar. When you add an activity to a track, a numeric identifier is assigned to it that differentiates it from other activities this patient may do. This identifier is also included in the name of the activity. Activity Type: The Activity Type drop down menu allows you to choose what kind of activity this is going to be. The track properties that appear in the main panel depend on what type of activity was selected from the drop down menu. Not all activities implement all the possible options, and so will not be shown. For more information on the different Activity Types click here. Activity ID: The Activity ID field allows you to modify the activities numeric identifier. By default when new activities are added they will be assigned a number that increments by ten. The first activity will be identified as 10, the second 20 and so on. Activities that are reordered in the activity list will keep their previous identifier. Predecessors: The Predecessors field works in conjunction with activity identifiers to make sure that patients correctly execute activities in order. When you add a new activity, it will automatically assign the Predecessor to be the activity directly above in the list. In the event you need to insert an activity in-between, make sure to update the Predecessor field with the new preceding activity. Note that predecessor activity relationships do not have to occur in any set order. You have full control over what activities precede subsequent ones merely by linking them together with the Predecessors field. Milestone: The Milestone field is another optional property that helps organize activities for reporting purposes. These milestones should be associated with the completion of the activity. You may select a milestone from the list or type your own. Start Time: The Start Time field is an optional property that allows you to specify if this activity has a minimum model time before it can start. Leaving it blank assumes no time requirement. This field assumes the format of days:hours:minutes, total number of minutes since time zero or as an expression. For example, if the highlighted activity in the list can only occur after 5 hours have passed in the simulation you could specify that by entering the time in the following format 0:5:0, 300 (5 times 60 minutes) or uniform(10, 20) which returns a value according to the uniform distribution with a minimum value of 10 and a maximum value of 20. Repeat Interval: This field allows you to determine if a given activity has an interval on which it will automatically repeat. If left blank, the activity will not repeat. This field assumes the format of days:hours:minutes, total number of minutes since time zero or as an expression. For example, if the highlighted activity in the list can only occur after 5 hours have passed in the simulation you could specify that by entering the time in the following format 0:5:0, 300 (5 times 60 minutes) or uniform(10, 20) which returns a value according to the uniform distribution with a minimum value of 10 and a maximum value of 20. Fixed Cost: The Fixed Costs is an optional parameters that allow you to assign a fixed monetary value to this activity.

Variable Costs Rate: The Variable Costs Rate field allows you to assign a rate of dollars per hour that this activity will cost. This field is also optional. Process Time: The Process Time field allows you to set the duration, in minutes, for a Process activity type. The value for this field may be a static number, as well as statistical or mathematical expressions. You may also chose from a list of configurable preprogrammed options from the dropdown menu. This property is only visible for activities that have a processing component Allocation Priority: Allocation priority allows you to set an activities variable priority level. Setting a higher number in this field assigns a higher priority to this activity versus any other activities that share staffing resources. For example, if a two activities exist that request the same resource, the activity with the higher priority will be serviced first, even if the lower priority activity requested the resource first. Preempt Resources: The Preempt Resource check box allows an activity to preempt resources involved with concurrent activities, and cause them to service this activity immediately. Interrupted activities will be resumed after the preempting activity has completed. Process Location: The Process location drop down menu allows you to specify where a process event will take place, if applicable, for this activity. This list is a dynamic list that will add any new resources as you create them in the model. This property is only visible for activities that have a processing component. Item/Message Destination: Item Destination is a property that only need be used if your model moves items, such as paper work or lab samples, or abstract messages between resources. This property allows you to tie item destinations to patient activities by locations and Activity ID. Reserve Current Location: The Reserve Current Location check box allows you to reserve a patients location should the patients activities cause her to leave the its current location. If your activities send the patient back to the vacated area it will be allowed to return to its original location within that area. Patient Destination: The Patient Destination is used in activities that require the patient to move to a new location. This list is dynamic, in that it will automatically add new Areas as resources are added to the model. These Areas are the locations you want patients to move to as part of their travel activity. This property is only visible for activities that have a transportation component. The next three sections, Staff, Equipment and Transportation Requirements tables have similar interfaces, and have a similar purpose. These sections allow you to assign Staff, Equipment or Transport resources to this activity. You may assign the resources as a shared resource group, an individual from a specific group or by references such as the last resource used from a previous activity. Each row in the table requests a resource that is required in order for this activity to begin. With version 3, there is a new interface to govern the assignment of staff to an activity:

1. Add a row to the staff table 2. Remove a row from the staff table 3. Resource Selection Menu Select a group directly Select the first used from a group Select a staff used in any earlier activity. Note that this option assumes that the designated activity actually has occurred already. Given the out of order execution capabilities for activities, it's important to assure that the desired "Earlier" activity has actually happened. 4. Supplemental Resource Selection menu Specific Member of a group Group to choose first from Activity from which to select previously used Staff

5. Requirement Row (only available with Used in Earlier Activity). Enter a row number that corresponds to a row in the Staffing Requirement table for the selected activity. 6. Keep a Resource with the patient indefinitely. The "Keep Resource" checkbox changes to "Release Resource" if two conditions are met: The requirement must be "Used in Earlier Activity" The requirement row being referenced must be keeping the resource The new Keep option allows the user to tie a resource (staff, equipment or transport) with a patient through multiple process steps. The Keep option replaces and simplifies the previously misunderstood same as above option in the staff table. Any Kept resource must be released using available pick options in the Advanced Functions of the Track Manager or with the function: releasemember() in code. Care must be used when using Keep with preempting tasks, and for now generally avoided. When a resource is Kept, it is no longer considered a candidate for requests that are made to its Group. So a Group that has for example, two member resources and one is currently Kept, only the non-Kept resource could fulfill the request. If a resource has been kept by an activity, has not been released yet and is not assigned to an activity, the resource will travel back to its group but still be unable to receive new requests. If you want a resource to be kept across multiple individual activity steps do the following: 1. Mark the Keep Resource check box on the activity at the start of the activity steps 2. In the Staff table for each subsequent activity, use the "Used in an Earlier Activity" option, and designate the Keeping activity as the entry in the Supplemental Resource Selection menu (#4 in the illustration above) 3. Use the "Release Resource" checkbox on the last activity of the keeping steps. To do this, The requirement must be "Used in Earlier Activity" and The requirement row being referenced must be keeping the resource.

Visuals

The Visuals tab gives you control over the appearance of the patients that will be associated with the track selected from the Track Tab. You may change the 3D shape, change the color as well as the spatial attributes of the patient. A preview pane is shown to the right so that you may see how your changes affect the appearance of the this track's patients. The accessories field allows you to further customize the appearance of Patients by adding additional shapes and textures to the Patient model.

Patient Classification

This tab allows you to assign a set of attributes that define patient "types". Enter the number of Patient Classifications you wish to have in the model in the Patient Classifications field, or click the up or down arrows to the right of the field to add or remove a PCI. Think of PCI as a collection of patient attributes that define the patient.,a combination of a Track, an Acuity, and any number of user defined labels. Each PCI represents a row in the table. The Track column defines which Patient Track (from the Patient Track Editor) this PCI will follow. Note that a track does not have to be exclusive to one PCI; Track 1 could be used for multiple PCI rows if desired. The Acuity column lets you change this PCIs patient Acuity value. Higher numeric values denote higher acuity patients and modeling objects are automatically configured to take acuity into account when Patients want to move to them. You may also add Labels to your patients using the Labels edit field. New labels will be added as additional columns on the PCI table and will be added to all patients created by Patient Arrivals Objects. Labels are a means to storing custom data as part of any FlexSim object, including patients. Labels may contain numeric information, text, executable code or even tabular data. Note the figure below on how to configure labels:

Once you have configured your PCI definitions, you may use the Properties defined on your Patient Arrivals objects to

establish how various PCI patients arrive into your model, such as according to a percentage chance of occurring or other expressions.

Files

The files tab allows you to work with track information as an external file. Here you may import an existing track from a FlexSim Binary file (.fst), Tab delimited file (.txt) or a comma delimited file (.csv). these file types are also available for export under the Export parameter group.

Activity Types

Process:
A simple delay time if no staff are defined and "Patients exclusivity required" is not checked. If patient's exclusivity is required, then the patient will need to be allocated before the activity and thus the delay time can begin. With this box checked, the patient could only be allocated by one activity at one time. It would only make sense to check this box if the box was also checked for at least one other activity that could possibly compete for allocation of the same patient at the same time. If staff are defined, then you will need to also define a "Process Location" because the staff will first be allocated, then travel to the process location, and then the process delay time will occur. The process location will not be allocated during the activity, so it is possible for multiple processes to occur simultaneously at the same process location unless restricted in other ways. The start time for this activity is when the activity is first spawned if no staff are defined, and it is the time when the first staff gets allocated if staff are defined. The finish time for this activity is when the process delay time is completed.

Process > Send Message:

Same as the Process activity above, with the addition that a message will be sent at the end of the process delay time. The message will be sent to the object chosen in the Message Destination drop down list. Messages can be sent to any object having an "OnMessage" or "Message Received Trigger". The message data is as follows: msgsendingobject = the patient msgparam(1) = a message identifier (not used, and therefore 0 by default) msgparam(2) = the row number corresponding to the ID value entered in the "associated Activity ID" field of the activity sending the message. This activity is considered finished after the process delay time has transpired and the message has been sent.

Process > Send Item:


Same as the Process activity above, with the addition that a flowitem will be sent to an Item class object at the end of the process delay time. Items will automatically be created as copies of the first flowitem defined in the Flowitem Bin (see toolbar). The item will be sent to the object chosen in the Item Destination drop down list. Messages can be sent to any object having an OnMessage or Message Received trigger. The flowitem will automatically have the following two labels given to it: PatientPointer = a numeric value referencing the patient whose activity sent the item. ActivityRow = the row number corresponding to the ID value entered in the "associated Activity ID" field of the activity sending the item. You may see the following two macros in some of the picklist options, so I provide their definitions here: PATIENT_LABEL = tonode(getlabelnum(item,LABEL_PatientPointer)) ACTIVITY_LABEL getlabelnum(item,LABEL_ActivityRow) This activity is considered finished after the process delay time has transpired and the item has been sent.

Move Equipment > Process:


A piece of equipment is first carried by one or more staff members to the "Process Location" and then a process delay time occurs. Here is a summary of the events associated with this activity: Allocate equipment Allocate staff members Staff travels to equipment Staff picks up equipment Staff travels with equipment to the process location Staff drops off the equipment at the process location (i.e. equipment placed back into model space). Process delay time Deallocate equipment Deallocate staff The start time for this activity is when the first staff member is allocated (not the equipment). The finish time for this activity is when the process delay time has completed.

Move Transport > Process:


Same as Move Equipment > Process activity, but a transport resource rather than an equipment resource will be moved.

Escort Patient > Process:


The patient is escorted by one or more staff members from their current location to an available location in the area defined by the activity's "Patient's Next Area" field. The next area can either be selected from the drop down list, or logically defined in the Advanced Function Editor. When this activity is spawned, the patient will be released to go to their next area. If a location within the next area is not available, then the patient will do one of the following: Walk unattended to another location, if there is another location connected to the patient's current location

that can accept it; i.e. the "Entrance Criteria For Next Patient" definition for the other location allows it and the location is available. Wait until a location within the patient's next area becomes available. This is the default behavior you will see most often by default. When a location becomes available, a second check is done to search for an available staff member from the list of staff defined for the activity. If no staff are available and the patient is in a PatientProcessing object rather than a PatientQueuing object, then the patient may also end up walking to another location as described above rather than stay put and wait for a staff member to become available. Here's an overview of the chain of events associated with an Escort Patient > Process activity when the patient does not walk unattended to another location first: Patient is assigned its next area. Patient is released from its current area. Location within next area becomes available. Location is reserved for the patient. Staff are allocated. Staff travel to patient. Patient is moved into one staff member. Staff travel to reserved location. Patient is moved from staff member into the location. Process delay time occurs. Staff are deallocated. A process delay time of zero is allowed. The activity start time is when the first staff member is allocated. The activity finishes at the end of the process delay time.

Transport Patient > Process:


The patient is moved via a transport and one or more staff members from their current location to an available location in the area defined by the activity's "Patient's Next Area" field. The next area can either be selected from the drop down list, or logically defined in the Advanced Function Editor. When this activity is spawned, the patient will be released to go to their next area. The patient will always wait where they are when either a location, a transport or sufficient staff are not available. Here's an overview of the chain of events associated with a Transport Patient > Process activity: Patient is assigned its next area. Patient is released from its current area. Location within next area becomes available. Location is reserved for the patient. A transport is allocated. Staff are allocated. Staff travel to transport. Transport is moved into one staff member. Staff travel to patient. Patient is moved into the transport which is in one of the staff members. Staff travel to reserved location. Patient is moved from staff member into the location. Transport is moved into the model space near the location. Deallocate the transport. Process delay time occurs. Staff are deallocated. A process delay time of zero is allowed. The activity start time is when the first staff member is allocated (not the transport). The activity finishes at the end of the process delay time; however the transport is made available sooner.

Patient Travels Unattended:


The patient walks unattended from their current location to an available location in the area defined by the activity's "Patient's Next Area" field. The next area can either be selected from the drop down list, or logically defined in the Advanced Function Editor. When this activity is spawned, the patient will be released to go to their next area.

If a location within the next area is not available, then the patient will do one of the following: Walk unattended to another location, if there is another location connected to the patient's current location that can accept it; i.e. the "Entrance Criteria For Next Patient" definition for the other location allows it and the location is available. Wait until a location within the patient's next area becomes available. Here's an overview of the chain of events associated with a Patient Travels Unattended activity when the patient is able to go to their intended area: Patient is assigned its next area. Patient is released from its current area. Location within next area becomes available. Location is reserved for the patient. Patient is moved into the model space at its current location. Patient walks to reserved location. Patient is moved into the location. The activity start time is when the location is available. The activity finishes when the patient is moved into the location.

Decision Point:
This Activity allows you to use the Next Activity field to explicitly cause another activity to begin. The Next Activity choice can be decision made between multiple activities according to conditions determined at runtime, such as percentages or patient conditions. This type of decision overrides Predecessor lists, start conditions and so on, and causes the chosen activity to immediately begin. It is useful anytime you wish to have a patients activities determined at runtime.

Custom Activity:
This activity provides the infrastructure for the modeler to assign staff, equipment and transports. Additional functionality is to be created by the modeler through the use of the advanced fields of the track manager. It's provided as a resource to the modeler to create patient activities that would be difficult to create with a regular activity.

Track Manager
Each Activity within a Track that you create for your model has access to more advanced features than the primary activity properties available from the Track Manager. These advanced features are organized into a separate window, accessible from the Advanced Functions button on the lower left hand side of the track manager window. This button is only available when the Activities tab is active. Which ever activity is currently highlighted in the list when the Advanced Functions button is pressed, is the activity whose advanced features will be shown. You may also navigate to the advanced functions of other activities in list with the use of the arrow buttons at the lower left corner of the window, without having to close and reopen the window. The title bar of the window will display the name of the currently active activity.

Following are descriptions for each of the advanced functions shown above. Short description are also available within FlexSim Healthcare by letting your cursor rest on the advanced function, allowing the hint text to pop up. The first three advanced functions, the Patient Message, Entry and Exit triggers are not bound to a single activity, and will occur whenever a patient which belongs to this track is sent a message, enters a location, or exits a location within the model. Patient Message Received Trigger: This trigger is provided as a means to execute specialized behavior or custom code as a result of a patient receiving a message sent by some other object. See the command documentation for the sendmessage() and senddelayedmessage() commands for more information. Patient Entry Trigger: This trigger will fire whenever a patient enters any location within the model. These are separate from the OnEntry triggers provided on the patient Processing and Patient Queuing objects, as those triggers are valid for the individual objects only. This trigger is for the patients, wherever they may go. Patient Exit Trigger: Similar to the Patient Entry Trigger, this trigger fires for any patient that leaves any location in the model. Not to be confused with the locationcentric trigger OnExit. Activity Start Condition: This function allows greater control over when or how an activity can start. Any custom code you may write must be a condition that can resolve to a true or false. If your condition is true, the activity is allowed to begin. If it evaluates false, the activity will not begin. Activity Started Trigger: This trigger event fires after the activity is allowed to begin. For this trigger to happen, all conditions that govern the start of this activity must be true. This includes all predecessor activities to be completed, the Start Time field, and the Activity Start Condition above. Activity Finished Trigger: This trigger fires after all tasks associated with this activity have completed, and activity specific results have been recorded. If the patient is in an exit, then the entire patient history will be saved; otherwise, a new activity to begin will be searched for, then variables for a repeating activity are reset. Process Location: This advanced function allows you to use logic to define where staff will be called to for the duration of this activity's process time. This field overrides the drop down menu from the Activities tab of the same name. The location specified should be a pointer to the desired location. Patient Destination: Similar to the Process location function, this field allows for logic statements to define where a patient will travel to next, rather than the simple drop down menu found under the Activities tab. This is only valid for activity types that cause the patient to move to a new location. Custom logic in this field should return a reference to a location object in the model. Item or Message Destination: This field allows for logic statements to define to what object an Item or a Message created by this activity will be sent. This is only valid for

the activity types Process > Send Item or Process > Send Message. Allows for more advanced sending of Items/Messages than the dropdown list for the regular activity properties will allow. Item Created Trigger: This trigger event fires after an Item is created but before it arrives at its destination. This is only valid for the activity type Process > Send Item. From here you may manipulate properties of the Item, such as color or shape before it arrives at an Item class object. Next Activity: The Next Activity field lets you step outside the natural process by which activities are begun and explicitly call an activity when the current activity ends. Activities that you want begun this way don't necessarily have to use predecessor activities. There might be a situation where an activity can start naturally according to it's predecessor list or due to an explicit call from Next Activity. However if you want an activity to only be begun due to an explicit call from Next Activity, uncheck the checkbox next to that activity's Predecessor List. This will disable that activity's predcessor field. Custom logic in this field must return a value that corresponds to a valid row in the patients activity table. In the picklist options, code is provided to convert activity IDs into row numbers for you. Although any activity may use this advanced field for starting other activities, this functionality was also made available from the new in 2.75 activity type, Decision Point. It is considered better "style" to use these Decision Point activities instead of the advanced function in order to better organize your tracks.

Patient Arrivals

The Patient Arrivals resource is used to generate patients that will travel through the model. A single Arrivals resource can create patients that will adhere to different patient tracks and different arrival schemes. The Arrivals resource can introduce patients to the model three different ways; using a tabular hourly arrivals per hour per day inter-arrival time patterns, or a scheduled sequence of arrivals. You may edit the behavior of the Arrival resource by double-clicking its 3D shape, opening the resources Properties window.

Properties

The first editable properties you will see at the top are the object Name and the Area. The name of the resource should be something both descriptive and unique; no two resources can have the same name. The Area property is used to route patients through the model and may not have any spaces or special characters in the name.

Tabs
Interarrival Times

Inter-arrival Times: This tab allows you to specify an interarrival rate of patients into the model. The interarrival time is a set period of time that the resource creates a new patient. This can be a period derived from a static number, or a statistical distribution. This interarrival rate will continue for as long as the model runs, creating new patients every period specified. You may also specify multiple arrival patterns of this type, each that can produce a different Patient Classification. This allows a single Patient Arrival object to implement multiple arrival patterns at once. Patient Classification Index (PCI): This field allows the user to write an expression that will will define the PCI assignment to patients created by the selected arrival pattern. Typing an integer value will produce patients according to the row number from the PCI table found on the Track Manager. This field also allows for expressions such as the P() percentage expression which will allow you to define up to 9 pairs of Percentage/Value pairs (e.g. P(70, 1, 30, 2) would produce PCI 1 for 70% of all patients and PCI 2 for 30% of all patients.)

Hourly Arrivals

The Hourly Arrivals tab is used to assign how many patients will enter the model per hour of the day over the course of a week. Note that the hours follow a 24 hour time format, rather than the 12 hour format. If you wish to use this arrival scheme, click the Activate check box at the top of the tab. Arrival Spacing: Patients my arrive during the period all at once, randomly spaced or evenly spaced, according the drop down menu. Patient PCI: This field allows expressions to be used to decide what PCI or mix of PCI's this arrival style will produce.

Appointments

Appointments: This arrival scheme allows you to specify a schedule or arrivals in the form of a table. In the cells under the Appointments column you can specify the arrival times patients are scheduled to arrive using the format days:hours:minutes, or total minutes since time zero in the model. The PCI column lets you assign a Patient Classifications to the scheduled patients. A value of zero in the Patient Classification Index field means that the settings under the Patient Classification tab will be used. The Arrival Time column is a read only column that will show you the real scheduled arrival time for a given patient . You may have an appointment schedule repeat itself using the Repeat Time parameter. For this parameter, specify an interval of time such that the schedule will reset after the last scheduled arrival. This interval can be whatever you need, whether it resets daily, monthly, etc. You may also use the Variability parameter to apply a variation to the appointment time. This will allow you to model the chance that a patient can be late or early around their scheduled time to arrive. The Arrival Time column that shows the real arrival time takes this variability into account in it's display. PCI: This column of the table allows you to assign to what PCI the appointment patient will belong. This field accepts integer values as well as expressions that can assign PCI's randomly.

Custom Arrivals

The Custom Arrival tab works similar to the Appointments tab but also incorporating some elements from the the Hourly Arrivals. For custom arrivals you define a number of "Periods". Arrival Spacing: Patients my arrive during the period all at once, randomly spaced or evenly spaced, according the drop down menu. Repeat Interval: Expression field to define how frequently this arrival pattern repeats itself. Each period may define a nubmer of patient that could arrive at the time defined in the first column. Each row of the table defines a period, attributes for the period are defined using the following columns of the table: Start Time: Define at what time in the model the arrival period occurs. End Time: Define the model time where the arrival period ends. Number of Arrivals: Number of patients to arrive during the period. This value may be derived from an expression. PCI: Assigns the PCI to patients created during the period. This value may be derived from an expression.

Other Property Pages


Triggers Labels Connections Visuals Stats

Patient Exit

The Patient Exit resource is the termination point for patients in the model. Patients should be routed here at the end of their track. Once a patient has entered the Exit the patient object is removed from the model completely and as such this is the last opportunity to record information about that patient in the model.

Properties

The first editable properties you will see at the top are the resource Name and the Area. The name of the resource should be something both descriptive and unique; no two resources can have the same name. The Area property is used to route patients through the model and may not have any spaces or special characters in the name.

Tabs
Entrance Criteria

Entrance Criteria: This tab implements the rule the Exit will use to accept patients for entry. This is a rule that says which patients have priority for this resource. You may chose options from the drop down menu, and as you become more proficient with the software you may wish to write your own custom rules.

Other Property Pages


Triggers Labels Connections Visuals Stats

Patient Queuing

The Patient Queuing resource can be used anywhere in your model where you want to simulate patients needing a general place to wait before continuing on with their track. Generally, someplace where downstream resource availability is exceeded by downstream supply would do well to have a queue point such as this. The Queuing are can be made to appear as a room of chairs, a row of beds or a line.

Properties

The first editable properties you will see at the top are the resource Name and the Area. The name of the resource should be something both descriptive and unique; no two resources can have the same name. The Area property is used to route patients through the model and may not have any spaces or special characters in the name.

Tabs

Entrance Criteria

Entrance Criteria: This tab implements the rule that the Queuing resource will follow for accepting patients for entry. This is a rule that says which patients have priority for this resource. You may chose options from the drop down menu, and as you become more proficient with the software you may wish to write your own custom rules. The Maximum Occupancy property allows you to set a maximum number of patients that are allowed into the resource. Note that this number has no bearing on the visual representation of the beds or chairs. If you give the resource a larger capacity than there are chairs, for example, the patients will begin to stack inside of each other on a filled chair.

Patient Condition

Patient Condition: The options in the Patient Condition tab deal with patients in the Queuing resource. The tab allows you to change information about the patients as time elapses in the model. You may set the time interval for evaluating patients with the Evaluate Patients numeric property. Patient Condition Changes: Property you can find options that will alter a patients acuity, such that you may simulate a patient worsening or improving as time goes on. Patient Leaves Early: Property you may also simulate patients making a decision about leaving the waiting room without being seen.

Layout

Layout: The layout tab accesses the properties that control the way the Queuing resource appears; how many rows/columns of chairs and beds and so on. These are purely graphic options, and will not have an impact on how many patients it can accommodate. See the Occupancy tab for the options that affect capacity.

Other Property Pages


Triggers Labels Connections Visuals Stats

Patient Processing

You will use the Patient Processing resource anytime you need to simulate some type of process, or forced delay that your patients need to experience. The resource itself is very flexible and can be made to serve the function of a triage area, patient bed, reception desk, etc.

Properties

The first editable properties you will see at the top are the resource Name and the Area. The name of the resource should be something both descriptive and unique; no two resources can have the same name. The Area property is used to route patients through the model and may not have any spaces or special characters in the name. By default, multiple Processing resources of the same type will have the same Area name so that the patient will go to the first available resource of the proper area. Simply change the Area name if you wish to avoid this kind of behavior. You may also change the 3D representation of this object using the drop down menu. If you change the

shape from the default bed this will automatically change the Name and Area fields to match.

Tabs
Entrance Criteria

Entrance Criteria: This tab implements the rule that the Processing resource will follow for accepting patients for entry. This is a rule that says which patients have priority for this resource. You may chose options from the drop down menu, and as you become more proficient with the software you may wish to write your own custom rules. You may also assign the maximum capacity of this object with the Maximum Occupancy parameter.

Maintenance

Maintenance: The maintenance tab allows you to set up maintenance events that might be needed to service this object. Since these events do not involve a patient, they are handled by the object directly as opposed to the track editor. Here you may assign a staff member or staff group to handle the maintenance. The duration specified in the Time field can be any numeric value, whether derived from a statistical distribution, looked up from a table, static value, etc.

Other Property Pages


Triggers Labels Connections Visuals Stats

Staff Group
The Staff group object is used to simulate the different groups of employees in the model. The staff group can be made to represent administrative staff, physicians, nurses and technician staff. You can use the Patient Track editor to assign these staff resources to appropriate patient activities.

Properties

In the Group properties you can see how many staff members are part of this resource, adjsut visual properties as desired, and chose whether or not they will follow a walking path network while doing travel activities. You may also use the Advanced Group editor button for more advanced group settings.

Under the Staff properties group, you can add or remove staff members with the Add and Remove Staff buttons. If you select one of the staff members from the list, its name will appear at the Name field to the right, allowing you to edit information about that staff member. You may change its color, skill level attribute and pay rate in dollars per hour. More advanced option are available from the Advanced Staff Editor button. New to version 3.0 of the software are options to alter the the appearance of individual staff members, such as gender, clothing colors, and so on. There is also a new Accessories inventory where you may add additional appearance touches to the staff, such as masks, name tags, or stethoscopes. Usable Members: This paramter is usually used in conjunction with the Experimenter, or other inmodel events where you may wish to dynamically alter the number of available staff within a group during runtime. The Floor Display property group lets you change the appearance of the colored floor space below staff memberss feet. You may change its color, positioning and size using the appropriate number fields. Member Selection Policy: This picklist governs how the Staff Group resource will parse resource requests to its Members. The Member Selection Policy is a rule that decides how the requests are handled based on criteria such as proximity or utilization balance.

Other Property Pages


(available from the Triggers Labels Connections Visuals Stats button)

Equipment Group

An Equipment Group resource will be used to simulate the availability and use of a piece of medical equipment such as a Crash Cart or a ventilator. Typically, this would be a shared resource of some kind rather than a stationary object such as an MRI machine. You can use the Patient Track editor to assign Equipment resources to appropriate patient activities.

Properties

In the Group properties you can see how many members are part of this resource. Choose what kind of equipment this resource will represent from the drop down menu. Click the checkbox to assign this resource to a walking path network while doing travel activities. You may also use the Advanced Group editor button for more advanced group settings.

Under the Equipment properties group, you can add or remove members with the Add and Remove buttons above the frame. If you select one of the members from the list, its name will appear at the Name field to the right, allowing you to edit information about that staff member. You may change its color, skill level attribute and the cost rate in dollars per hour. More advanced option are available from the Advanced Equipment Editor button. Usable Members: This paramter is usually used in conjunction with the Experimenter, or other in-model events where you may wish to dynamically alter the number of available equipment within a group during runtime. The Floor Display property group lets you change the appearance of the colored floor space below the resources base. You may change its color, positioning and size using the appropriate number fields. Member Selection Policy: This picklist governs how the Equipment Group resource will parse resource requests to its Members. The Member Selection Policy is a rule that decides how the requests are handled based on criteria such as proximity or utilization balance.

Other Property Pages


(available from the Triggers Labels Connections Visuals Stats button)

Transport Group

A Transport Group resource will be used to simulate the availability and use of a mode of transportation such as a wheelchair. Use this resource when you want to represent when the patient cannot be transported under their own power. You can use the Patient Track editor to assign Transportation resources to appropriate patient activities.

Properties

In the Group properties you can see how many members are part of this resource. Choose what kind of equipment this resource will represent from the drop down menu named Shape. Click the checkbox to assign this resource to a walking path network while doing travel activities. You may also use the Advanced Group editor button for more advanced group settings.

Transports properties: You can add or remove staff members with the Add and Remove Staff buttons. If you select one of the staff members from the list, its name will appear at the Name field to the right, allowing you to edit information about that staff member. You may change its color, skill level attribute and the cost rate in dollars per hour. More advanced option are available from the Advanced Transport Editor button. Number of Active Transports parameter is usually used in conjunction with the Experimenter, or other in-model events where you may wish to dynamically alter the number of available transports within a group. The Floor Display property group lets you change the appearance of the colored floor space below the resources base. You may change its color, positioning and size using the appropriate number fields. Member Selection Policy: This picklist governs how the Transport Group resource will parse resource requests to other connected groups or staff. The Member Selection Policy is a rule that decides how the requests are handled based on criteria such as proximity or utilization balance.

Other Property Pages


(available from the Triggers Labels Connections Visuals Stats button)

Elevator Bank
The Elevator Bank object is designed to allow easy implementation of elevators that may exist in multi-floor healthcare facilities. Their function is designed to be fairly intuitive and users should not need to make a lot of changes to the Elevator Bank Properties in order to get them working.

Properties

The Elevator Bank properties are designed to function very similar to the other resources such as staff and equipment. You can see how many individual Elevators are members of the bank, adding and removing members as needed. Elevators have specific logic that allows them to work together and be efficient with handling traveler requests to use them. You may also use the Advanced Editor button for more advanced group settings. One of the unique requirements of the elevator, in contrast to the other resources, is that Elevators require the use of Paths in order to know where travelers are and where they want to go. This means that you will need to create Pathways up in the Z-axis of your model that represent the floor stops of where the elevator doors will open to receive or disembark passengers. Under the Elevator's properties group, you can add or remove members with the Add and

Remove buttons. If you select one of the members from the list, its name will appear at the Name field to the right, allowing you to edit information about that member, such as Speed or surface volume. Usable Members: This parameter is usually used in conjunction with the Experimenter, or other in-model events where you may wish to dynamically alter the number of available elevators within a group during runtime. Floor Display: Lets you change the appearance of the colored floor space below the elevator bank. You may change its color, positioning and size using the appropriate number fields. Member Selection Policy: This picklist governs how the Elevator Bank will parse resource requests to its Members. Speed: How fast the Elevator is permitted to travel. Floor Space (sq. meters): This property allows you to adjust what the capacity if the Elevator is. Notice that its unit is in square meters as to be me more realistic than a number of travelers. This way Elevators know that patients on Gurneys or wheelchairs take up more space than a person standing up.

Other Property Pages


(available from the Triggers Labels Connections Visuals Stats button)

Alternate Group

The Alternate Groups object allows you some extra flexibility with your Staff, Equipment and Transport resources. This resource can work as a go-between for coordinating the efforts of multiple Staff groups. For example, in the case that one staff group were to be the primary care giver for a specific activity but a second staff group could also be called upon in the event no member of the first were available.

Tabs
Members

Member Selection Policy: This picklist governs how the Alternate Group resource will parse resource requests to other connected groups or staff.The Member Selection Policy is a rule that decides how the requests are handled based on criteria such as proximity or utilization balance. For more on adding and removing Members to the Alternate Group, refer to the Connections tab information located here.

Other Property Pages


Triggers Labels Connections Visuals Stats

Item Arrivals

This object is the first of the resources that do not deal with patients directly. Its function is to create items involved in processes centered on the other item-centric resources. Item Arrival objects can create items per an inter-arrival rate, a scheduled arrival list, or simply from a defined arrival sequence.

Tabs
Source
Arrival Style: This is used to specify the way that the source creates items. Inter-Arrival time: After a set period of time, the source creates one item. This repeats until the model is stopped. Arrival Schedule: The source follows a table that defines when items are created, how many there are, and what item types are assigned to them. Arrival Sequence: The source follows a table that defines what order items are created in. Items are created as fast as the source can move them downstream. FlowItem Class: This is used to define what class of item the source will create. To edit and view item classes, use the Items button in the toolbar. Inter-Arrivaltime Usage These fields define how the source creates items when inter-arrival time is selected as the arrival style. Arrival at time 0: If this is checked, one flow item will be created at time 0. The next will be created at the end of the first inter-arrival time. Item Type: Flow items that are created will be assigned the item type defined here. Inter-Arrival time: A function that returns the amount of time the source should wait before creating the next item. The model must be compiled after changing this parameter Arrival Table Usage: These fields define how the source creates items when arrival

schedule or arrival sequence is selected as the arrival style. Number of Arrivals: This specifies how many rows are in the arrival table. Refresh: Pressing this button will update the on-screen table after changing the number of arrivals. Number of Labels: This specifies how many columns are in the arrival table. Additional columns will be added for labels and their initial values that will be added to the items when they are created. Refresh Arrivals/Labels: Pressing this button will update the on-screen table after changing the number of arrivals/labels. Repeat Schedule/Sequence: If this box is checked, the schedule or sequence will continually repeat itself until the model is stopped. In the case of a schedule, the arrival defined in row 1 will occur 0 seconds after the time defined for the arrival in the last row. This means that the arrival time for the very first row of the table is only used once for a given simulation. Note that this initial delay can be used as a warmup period. If you would like to specify an interval time between the arrival time of the last row and the arrival time of the first for when repeated, then add another row to the end of the table and specify a quantity of 0. Add Table to MTEI: This buttons adds the table as a row in the Multiple Table Excel Import. ArrivalTime: This is the time that the arrival will occur. ProductName: All the items that the source creates during this arrival will be given this name. Item type: All the items that the source creates during this arrival will be given this item type. Quantity: This number specifies how many items will be created during this arrival.

Other Property Pages


Flow Triggers Labels Connections Visuals Stats

Item Exit

The sink is used to destroy items that are finished in the model. Once a item has traveled into an Exit, it cannot be recovered. Any data collection involving items that are about to leave the model should be done either before the item enters the Exit or in the Exits OnEntry trigger.

Sink

Recycling Strategy: The recycling strategy drop-down list lets you specify how the Sink recycles items. Recycling items can significantly increase the speed of your

model. By default, the Sink simply destroys items that enter. To configure the sink to recycle items, select from the drop-down list a item in the item bin that this sink's items originate from. If you configure a Sink to recycle items any changes made to the items during the model run, you will need to change them back to their original state from the entry trigger of the sink, so that when they are recycled, they will have the correct data, visuals, etc.

Other Property Pages


Flow Triggers Labels Connections Visuals Stats

Item Queuing

The queue is used to store items when a downstream object cannot accept them yet. By default, the queue works in a first-in-first-out manner, meaning that when the downstream object becomes available, the item that has been waiting for that object the longest will leave the queue first. The queue has options for accumulating items into a batch before releasing them.

Tabs
Queue
Maximum Content: This is the maximum number of items the queue can hold at once. Lifo: If this box is checked the queue will act as a "last in first out" (lifo) queue, otherwise it will act as a "first in first out" (fifo) queue. Batching These fields define the queues batching abilities. Perform batching: If this box is checked, the queue will accumulate items into a batch before releasing them downstream. Accumulation continues until either the target batch size is met or the max wait time expires. If this box is not checked, no batching will occur, and items may leave as soon as downstream objects are available. Target Batch Size: This number defines the size of the batches that the queue will gather before sending the items downstream. Items are sent downstream individually. Max Wait Time: This number is the maximum length of time that the queue will wait before sending the items downstream. If this time expires and the batch size has not been met, the currently collected batch will be released anyway. If 0 is specified in this field, then there is no maximum wait time, or in other words the queue will wait indefinitely. Flush contents between batches: If this box is checked the queue will not allow new items to enter until the entire current batch has left. Visual

These properties define how the queue locates the items within itself when they enter. Item Placement: This defines how the items are placed in the queue visually. Stack Vertically: The items are stacked on top of each other. The item at the bottom of the pile is the one that has been in the queue the longest. Horizontal Line: The items are lined up horizontally. The one closest to the output ports of the queue is the one that has been in the queue the longest. Stack inside Queue: The items are stacked in rows inside the queue. The items' positions will move if a product ranked before them is taken out of the queue. If you would like the product positions to stay the same once they are in the queue, then have the queue be LIFO by having downstream objects pull only the last product in the queue. Do Nothing: Items are all placed at the same point in the queue. This may make it appear as if the queue is only holding one item. Stack Base Z: This number defines the height where the queue begins placing items that are being stacked vertically or inside the queue.

Other Property Pages


Flow Triggers Labels Connections Visuals Stats

Item Processing

The processor is used to simulate the processing of items in a model. The process is simply modeled as a forced time delay. The total time delayed is split between a setup time and a process time. The processor can process more than one item at a time. Processors may call for operators during their setup and/or processing times. When a processor breaks down, all of the items that it is processing will be delayed.

Tabs
ProcessTimes

Setup Time: This pick list defines the amount of time that the processor waits after receiving a

item to begin processing that item. See Setup Time pick list. Use staff for setup: If this box is checked the object will call for one or more Staff resources during its setup time. The Staff will be released after the setup time has expired. Number of Setup Staff: This parameter is only visible when the "Use Staff for Setup" box is checked. This number determines how many Staff resources the object will use during its setup time. Use same staff for both Setup and Process: This parameter is only visible if both of the "Use Staff" boxes are checked. If this box is checked, the Staff that were called for setup time will be utilized during process time. If this box is not checked, the Staff used for the setup time will be released and new Staff will be called for the process time. Different Staff can be called using a special pick option in the "Staff" parameter. Process Time: This pick list determines how long a processor spends processing a single item. Use Staff for Process: If this box is checked the object will call for one or more Staff resources during its processing time. The Staff will be released after the process time has expired. Number of Process Staff: This parameter is only visible when the "Use Staff for Process" box is checked, and the "Use same staff for both Setup and Process" box is not checked. This number determines how many Staff resources the object will use during its process time. Staff Staff: This field is only visible when either of the Use Staff boxes is checked. This pick list returns a reference to a specific Staff resource or a Group object that the object will request during setup or process time. See Process Dispatcher picklist. Priority: This parameter is only visible when either of the "Use Staff" boxes is checked. This value sets the priority of the task sequence that will be sent to the Staff chosen from the Staff pick option. Staff resources generally sort task sequences so that task sequences with higher priorities will be performed first. Task sequences with the same priority will be performed in the order that they were received. Preempt: This parameter is only visible when either of the "Staff" box is checked. If this box is checked, the task sequences sent to the Staff resource or Group will automatically preempt whatever the Staff is doing at the time. This may cause the Staff to perform tasks that would normally not be allowed.

Other Property Pages


Flow Triggers Labels

Connections Visuals Stats

Item Combining

The combiner is used to group multiple items together as they travel through the model. It can either join the items together permanently, or it can pack them so that they can be separated at a later point in time. The combiner will first accept a single item through input port number 1 before it will accepts the subsequent items through the remaining input ports. The user specifies the quantity of subsequent items to accept through input ports two and higher. The setup/process times will begin after all subsequent items required by the user have arrived at the resource.

Tabs
ProcessTimes

Setup Time: This pick list defines the amount of time that the processor waits after receiving a item to begin processing that item. See Setup Time pick list. Use staff for setup: If this box is checked the object will call for one or more Staff resources during its setup time. The Staff will be released after the setup time has expired. Number of Setup Staff: This parameter is only visible when the "Use Staff for Setup" box is checked. This number determines how many Staff resources the object will use during its setup time. Use same staff for both Setup and Process: This parameter is only visible if both of the "Use Staff" boxes are checked. If this box is checked, the Staff that were called for setup time will be utilized during process time. If this box is not checked, the Staff used for the setup time will be released and new Staff will be called for the process time. Different Staff can be called using a special pick option in the "Staff" parameter. Process Time: This pick list determines how long a processor spends processing a single item. Use Staff for Process: If this box is checked the object will call for one or more Staff resources during its processing time. The Staff will be released after the process time has expired. Number of Process Staff: This parameter is only visible when the "Use Staff for Process" box is checked, and the "Use same staff for both Setup and Process" box is not checked. This number determines how many Staff resources the object will use during its process time. Staff Staff: This field is only visible when either of the Use Staff boxes is checked. This pick list returns a reference to a specific Staff resource or a Group object that the object will request during setup or process time. See Process Dispatcher picklist. Priority: This parameter is only visible when either of the "Use Staff" boxes is checked. This value sets the priority of the task sequence that will be sent to the Staff chosen from the Staff pick option. Staff resources generally sort task sequences so that task sequences with higher priorities will be performed first. Task sequences with the same priority will be performed in the order that they were received. Preempt: This parameter is only visible when either of the "Staff" box is checked. If this box is checked, the task sequences sent to the Staff resource or Group will automatically preempt whatever the Staff is doing at the time. This may cause the Staff to perform tasks that would normally not be allowed.

Combiner
Pack/Join/Batch: Selects the mode that the Combiner is operating in.

Recycle To (Join mode only): In join mode, the objects that come in through ports greater than 1 are destroyed after the combiner is finished processing. Rather than destroying the extra items, you can use this option to recycle them to a specific item recycling bin. To learn more about recycling, refer to the Item Exit Page. Convey Items Across Combiner Length: If checked, items will travel across the Combiner during their process time. Components list: This table is used to define how many of each type of item the combiner will collect before sending the completed collection downstream. The combiner will use the item that arrives through input port one as the container object and will only accept one of them. Each row in the table represents arrivals from input ports numbered two and above. If you make additional connections while this window is open, you will need to close the Properties window and reopen it in order for your changes to register. To update this list dynamically during a model run, use the Update Combiner Component List pick list option in the OnEntry trigger. TargetQuantity: The required number of items to be received through the associated input port for each operation.

Other Property Pages


Flow Triggers Labels Connections Visuals Stats

Item Separating

The separator is used to separate an item into multiple parts. This can either be done by unpacking a item that has been packed by a Combining object or by making multiple copies of the original item. The splitting/unpacking s done after the process time has completed.

Tabs
ProcessTimes

Setup Time: This pick list defines the amount of time that the processor waits after receiving a

item to begin processing that item. See Setup Time pick list. Use staff for setup: If this box is checked the object will call for one or more Staff resources during its setup time. The Staff will be released after the setup time has expired. Number of Setup Staff: This parameter is only visible when the "Use Staff for Setup" box is checked. This number determines how many Staff resources the object will use during its setup time. Use same staff for both Setup and Process: This parameter is only visible if both of the "Use Staff" boxes are checked. If this box is checked, the Staff that were called for setup time will be utilized during process time. If this box is not checked, the Staff used for the setup time will be released and new Staff will be called for the process time. Different Staff can be called using a special pick option in the "Staff" parameter. Process Time: This pick list determines how long a processor spends processing a single item. Use Staff for Process: If this box is checked the object will call for one or more Staff resources during its processing time. The Staff will be released after the process time has expired. Number of Process Staff: This parameter is only visible when the "Use Staff for Process" box is checked, and the "Use same staff for both Setup and Process" box is not checked. This number determines how many Staff resources the object will use during its process time. Staff Staff: This field is only visible when either of the Use Staff boxes is checked. This pick list returns a reference to a specific Staff resource or a Group object that the object will request during setup or process time. See Process Dispatcher picklist. Priority: This parameter is only visible when either of the "Use Staff" boxes is checked. This value sets the priority of the task sequence that will be sent to the Staff chosen from the Staff pick option. Staff resources generally sort task sequences so that task sequences with higher priorities will be performed first. Task sequences with the same priority will be performed in the order that they were received. Preempt: This parameter is only visible when either of the "Staff" box is checked. If this box is checked, the task sequences sent to the Staff resource or Group will automatically preempt whatever the Staff is doing at the time. This may cause the Staff to perform tasks that would normally not be allowed.

Separator

Unpack: If this button is checked, the separator will assume that the item that entered contains other items that need to be removed. Split: If this button is checked, the separator will make duplicate copies of the entering item. Convey Items Across Separator Length: If checked, items will travel across the Separator during their process time. Split/Unpack Quantity: This pick list returns how many items will be unpacked or duplicated by the separator. Refer to the split quantity pick list. Recycle From (Split mode only): In split mode, the items that are created can be pulled from recycled items rather than creating a new copy. You can use this option to specify what type of item should be created. To learn more about recycling, refer to the Sink Page.

Other Property Pages


Flow Triggers Labels

Connections Visuals Stats

Item Conveyor

Overview
The Conveyor is used to move flowitems through the model along a set path. The path is defined by creating different sections in the conveyor. Each section can be either straight or curved. Curves are defined by the angle that they turn and their radius. Straight sections are defined by their length. This allows the conveyor to have as many curves and bends as it requires. The conveyor can be either accumulating or non-accumulating.

Details
The Conveyor operates in one of two different modes, accumulating or nonaccumulating. In accumulating mode, the conveyor acts like a roller conveyor. Flowitems can accumulate even when the end of the conveyor is blocked. In nonaccumulating mode, the conveyor operates like a belt conveyor. If the conveyor is blocked then all flowitems on the conveyor will be stopped.

Receive/Release Logic
When a flowitem arrives on the conveyor, it starts with its front edge at the starting edge of the conveyor. It begins to convey down the length of the conveyor. Once the flowitem's full length has conveyed over the start edge of the conveyor, the conveyor opens its inputs again to receive another product. When the flowitem's front edge hits the end of the conveyor, the conveyor releases the flowitem. Note on the first section being a curved section: If the first section of the conveyor is a curved section, then entering flowitems will convey onto the conveyor as if the last section of the previous conveyor were also a curved section. Thus the flowitem will actually curve onto the conveyor. This may not be what you want. You may want the flowitem to flow straight onto the conveyor. To do this, instead of having the first section of the conveyor be a curved section, insert a straight section as the first section with length of 0. Then flowitems will convey straight onto the conveyor. The Conveyor will only receive one flowitem at a time, and will only release one flowitem at a time. What this means is that, if flow items are being transported into or out of the conveyor using a Staff resource, only one flowitem can ever be in transit into it, and only one can wait for a transport to pick it up from the conveyor at a time. This is important to know if you want to have several resources pick up flowitems and transport them to the conveyor simultaneously. In order to do this, you would need to have a queue in front of the conveyor since a queue can receive multiple products in

transit simultaneously.

Speed Constraints
The Conveyor does not implement acceleration or deceleration of flowitems. Also, the speed value of the conveyor should not be changed dynamically during a simulation run. Instead, use the changeconveyorspeed() command.

Aligning Conveyors
The Conveyor also has a simple ability to align subsequent conveyors. By holding down the 'X' key and clicking on a conveyor, the conveyor connected to its first output port will be re-aligned to be flush with the conveyor's end point.

Conveyor X Size
You may notice that the actual size of the conveyor (the size of its yellow box when selected) is not the same as the conveyor's length. Changing the conveyor's y size will correctly change the conveyor width. Changing the conveyor's x size, on the other hand, will change the width of the conveyor's legs.

Upstream Blocked Length Notification


On the Properties window of the conveyor, there is a checkbox to tell the conveyor to notify upstream of blocked content. This allows for proper accumulation on multiple conveyors in series. However, the inter-conveyor messaging involved in this operation is very processor intensive, and can slow your model down if used ubiquitously, so use this feature only where necessary. Also, photo eyes are not supported when this feature is used.

Changing Speeds Across Conveyors


You may notice that if you have a model with a fast conveyor followed by a slow conveyor, products will often overlap in the transition. This is a visualization glitch and does not affect output of your model as long as the transfer is not a branch into several conveyors. Even if it is at a branch point, you can fix it by putting the item on a single slow and very short conveyor before the branch point.

States
Empty: There are no flowitems on the conveyor. Conveying: All flowitems are conveying down the conveyor. Blocked: The front flowitem has reached the end of the conveyor and has been released, but has not been accepted by a downstream object yet. Note that this doesn't

necessarily mean that all flowitems are stopped, as in the case of an accumulating conveyor. Waiting for Transport: The front flowitem has reached the end of the conveyor and has been released and accepted by a downstream object, but the transport hasn't picked it up yet.

Tabs
Conveyor
Operation These properties define how the conveyor functions. Accumulating: If this box is not checked, the conveyor is non-accumulating. In a non-accumulating conveyor, the entire conveyor stops if a flowitem reaches the end and cannot exit. If accumulating, the flowitems will continue traveling the length of the conveyor until they run into a stopped flowitem or reach the end. The distance between accumulated flowitems is determined by the spacing rule. Speed: This number defines the speed that flowitems travel at as they move down the conveyor. Maximum Content: This number sets a limit on how many flowitems can be on the conveyor at one time. The maximum number of flowitems on a conveyor is usually determined by the length of the conveyor and the size of the flowitems, but this allows you to screen it even more. Spacing Value: A flowitem will stop when its front edge is a certain distance away from the front edge of the flowitem in front of it. That distance is defined by the spacing value. This number is used in different ways, as you define in the Spacing Rule. Spacing Rule: This defines how much space the conveyor leaves between flowitems that are on it. Item Size: A flowitem will stop moving when it reaches the flowitem in front of it. Item Size + Spacing Value: A flowitem will stop when it is a certain distance from the back of the flowitem in front of it. That distance is defined by the spacing value. Spacing Value: A flowitem will stop when it is a certain distance from the front of the flowitem in front of it. Item Size * Spacing Value: A flowitem will stop when it is a certain distance from the back of the flowitem in front of it. That distance is defined by the preceeding item's size times the spacing value. Spacing Orientation: If the Spacing Rule includes the item's size, this field

determines which dimension of an item defines its size on the conveyor. Options are x, y, or z size. Orient Z, Orient Y: These fields are for visual purposes and do not affect the operation of the conveyor. They are used in conjunction with the Spacing Orientation field to orient the flow items correctly. They define a rotation in degrees around the z and y axes of the conveyor for flow items to be rotated. For example, if in the Spacing Orientation field Item Y Size is chosen instead of the default Item X Size, you will want to specify the Orient Z field as either 90 or 270, so that the y dimension of the flow item aligns with the length of the conveyor, instead of the x size. If Item Z Size is chosen, then you will want the Orient Y field to be either 90 or 270. Virtual Length: This field allows you to define a specific length for the conveyor, different from the actual length of its layout. If 0 is input (default), the conveyor's normal layout length will be used. Otherwise, the value in this field will be used as the conveyor's length. This field is used if you want to simulation a very long conveyor without having it traverse a huge distance in your model, or if you want to specify an exact distance. Scale Product with Virtual Length: This is for visual purposes and does not affect the operation of the conveyor. If you have defined a very large Virtual Length, this field allows you to scale the size of the products that flow down the conveyor so that they don't overlap. For example, if the conveyor's layout length is 10, but you've specified a virtual length of 100, then items with a size of 1 would only take up 1/100th of the conveyor's virtual length. This is 0.1 units in the real layout, but since a flow item is 1 unit, it overlaps with other flow items. If this box is checked, then the size of the flow item will be shrunk to 0.1 units. Notify Upstream of Blocked Length: This tells the conveyor to notify upstream conveyors when products on the conveyor extend past the conveyor's leading edge. Visual These properties define how the conveyor looks in the model. They do not affect the conveyor's operational functionality. These properties in combination give you unlimited flexibility in the look of your conveyor. Often configuring these settings is done by trial and error, but you should be able to learn quickly how each parameter affects the conveyor's look. Texture: This file will be drawn on the conveyor to change its basic appearance. The texture is divided into three parts. The left third of the texture is drawn onto the left side skirt, the middle third is drawn on the top, and the right third is drawn on the right side skirt. Texture Length: This number defines the length along the plane of the conveyor to stretch one copy of the texture before repeating the texture.

Product Z Offset: Changing this number will change how far above or below the conveyor the flowitems are drawn. A value of 0 puts the items directly on the conveyor. A negative value will put the items below the conveyor's plane. Move While Paused: By default, the conveyor's texture animation is only updated as the simulation runs. If this box is checked, the conveyor will animate with every refresh of the 3d window in addition to refreshing while the model is running. Infinite Increment: Checking this box makes it so that the conveyor's texture is animated smoothly instead of at fixed increments. You would use this option with a texture that moves along the conveyor, such as a belt texture. Texture Increment: The conveyor's texture animation is updated at particular increments. For example, the roller texture has 32 rollers in its texture. The texture is only animated by shifting the texture by the specified value. This makes the animation look like individual rolling wheels instead of a flat rolling texture. You can set the Texture Increment to 1 to prevent the texture from animating. Side skirt follows contour of conveyor (not floor): If this box is checked, the side of the conveyor will be drawn starting a certain distance away from the conveyor. If it is not checked, it is drawn starting a certain distance away from the floor (the z location of the conveyor). Either way, the sides connect to the conveyors contour. Side Skirt Dimension: This value is used to determine how tall the skirt is. Side Skirt Offset: This value is used to offset where the side skirt is drawn. Leg base relative to conveyor: If this box is checked, the legs of the conveyor will be drawn starting a certain distance away from the conveyor. If it is not checked, they are drawn starting a certain distance away from the floor (the z location of the conveyor). Either way, the sides connect to the conveyors contour. Leg base dimension: This value is used to determine where the legs of the conveyor begin.

Layout
Initial Z Rotation: This number sets the rotation of the conveyor, or the direction of the first section of the conveyor. This is the same as editing the Z rotation in the Properties window. Add: This button adds a straight section to the conveyor after the currently selected row. It adds the section to the end of the conveyor if nothing is selected in the table. Remove: This button deletes the currently selected row of the section table. It deletes the last row if nothing is selected in the table. Up/Down Arrows: These buttons move the selected section of conveyor up/down in the list, effectively moving the section of the conveyor.

Type: This list lets you choose whether the currently selected section is curved or straight. Length: This number defines how long the section is if it is a straight section. The value is ignored if it is a curved section. Angle: This number defines the angle in degrees that the segment will turn if it is curved. It can be positive or negative and can be greater than 360. This value is ignored if the section is a straight section. Radius: This number defines the radius of the turn in the curved section. The radius is measured from the center of the turn to the center of the conveyor. This value is ignored if the section is a straight section. Rise: This value defines the difference in height between the start of the segment and the end. For example, if this value is 3, the segment will end 3 units higher than it began.

Other Property Pages


Flow Triggers Labels Connections Visuals Stats

NetworkNode Tab Page

For more detailed information, see Paths documentation. Maximum Travelers at Node: This number defines how many transporters that are not traveling on the network can be stationed at the node. This would represent the transporters that are not currently executing a travel task, but are doing other things while "stationed" at the node. Side Offset: This number defines a distance to the right of outgoing paths that travelers will be offset. It does not affect the distance that the traveler travels, but is purely for visual purposes, so travelers going in different directions along the same path don't run over each other.

Paths
Note on Path connections: Each path between two NetworkNodes contains two oneway connections. This page defines behavior only for the connections extending from this NetworkNode to other Path. If you would like to edit behavior for connections extending from other Path to this NetworkNode, then open the Properties window of those other nodes. Name: This field allows the user to name each connection in the network. These names should be descriptive of any special purpose this connection has in the model. Connection Type: This drop-down list allows the user to define how this connection behaves. There are three options. No Connection: Transporters cannot travel on this connection. The connection is drawn in red in the view window. Passing: Transporters are allowed to pass each other on this connection. The connection is drawn in green in the view window. No Passing: Transporters will not pass each other on this connection. The minimum distance between transporters on the path can be set by the user in the Spacing field of the dialog. These connections are drawn in yellow in the view window. Spacing: This number determines the minimum distance allowed between two transporters on a connection that is designated as no passing. This is the distance from the back of one traveler to the front of the traveler behind it. Speed Limit: This number determines the maximum speed that a traveler can travel along this connection. Current Distance: This number shows you the current distance that is being simulated for that connection. If the virtual distance is specified as 0, then it will be the actual distance of the spline path. Otherwise it will be the distance that is specified in the virtual distance field. Virtual Distance: This number let's you specify an exact distance for the connection. Alternate Exit: Travelers arriving at a location via the current node, may return to the path network via the node associated with this connection.

Other Property Pages


Triggers Labels Visuals

Graphic Display
Overview
Graphic Displays are used to decorate the model space with props, scenery, text, and presentation slides in order to give the model a more realistic appearance. They can be something as simple as a colored box, background, or something as elaborate as an imported 3D graphic model or presentation slide.

Graphic Displays operate different than the other objects in FlexSim Healthcare. Normally, you create an object, position it where you like, then edit its properties. However, when Graphic Display objects are created, the Properties window appears immediately, allowing you to edit the object before you place it. The default properties set the Graphic Display to be a screen locked clock that displays the day, and the simulation time in Hours:Minutes:Seconds. Feel free to play around with the different settings to get different ideas on how to use the Graphic Display. There are three more common ways that Graphic Displays are used.

Using a Graphic Display as Stationary Text


This is the default setting for the Graphic display. in the Text Display list, there are many different things that the Graphic Display can show. Use this to enhance the visual aspect of your model, and for a quick reference to some basic but useful numbers. Below is the list of available options. Keep in mind that these options will also be available in non-

billboard mode.

Using a Graphic Display as Plain Text (No Billboard)


If you want the Graphic Display to be next to an object instead of locked in the corner, select No Billboard from the Billboard Mode list. This will allow you to put the text next to an object to show basic statistics of that object, or you could use it to label objects, or even sections of your model (To see an example of this, see the tutorials. In each tutorial, a Graphic Display object has been placed next to each object, showing its name, to make it easier for the user to recognize which object is which).

Using a Graphic Display as an Imported Shape


This option allows you to make your model more realistic by adding 3d shapes to it. To enable this mode, select Imported Shape from the Visual Display list. Notice that the options for the Graphic Display change depending on which Visual Display you are using. There is now a field where you can browse for a shape that you have created (.wrl or .3ds). Use this mode to decorate your model with realistic shapes to help your model feel more like your actual system.

Other Property Pages


Triggers Labels Visuals

Advanced
OnResourceAvailable
Overview
This trigger is available for either a Group object or a Staff resource and behaves a little differently on each. For a Group, the trigger is fired whenever a downstream Staff resource becomes available. For a Staff, the trigger is fired whenever that Staff finishes a task sequence. If the function returns a 0, the Group or Staff will do its own dispatching logic. If the function returns a 1, it will not do anything, and assumes all dispatching logic is done with this trigger using the movetasksequence() and dispatchtasksequence() commands.

Access variables
current: the current object port: for a Group, this is the output port of the Group object; for a Staff member that has just finished a task sequence, the port value is 0 resource: for a Group object, this is the downstream resource that has become available; for a Staff member, this value is the Staff itself (or the same as current) nextts: this value is the next task sequence in the task sequence queue lastts: for a Group, this value is always NULL; for a Staff, this value is the task sequence that was just completed before it became available

Dispatcher Properties

Pass To : This pick list returns the output port number that the task sequence should be dispatched to. If 0 is returned, then the task sequence will be queued up using the below mentioned queue strategy, and then will be dispatched to the first available

mobile resource. If :1 is returned, then the Group will do absolutely nothing. In such a case you would use the movetasksequence() and dispatchtasksequence() commands to execute dispatching logic yourself. See Pass To pick list. Queue Strategy:This pick list returns a "priority" value for the task sequence that is used to rank it in the objects task sequence queue. By default, it will simply return the priority value given to the task sequence when it was created, but the user can also customize task sequence priorities in this field. See Queue Strategy pick list.

Parameters Properties

Capacity:This number is maximum number of patients that the Staff resource can escort at a given time or items it can carry. Max speed : This is the fastest that the Staff resource can travel. Acceleration : This number is how fast the Staff gains speed until it reaches its maximum speed or needs to slow down to reach its destination node. Deceleration : This number is how fast the Staff loses speed as it approaches its

destination. Flip Threshold:When the angle between the Staff and the destination node meets or exceeds this value, the Staff will flip (mirror image) in order to be facing the correct direction. This option will not affect the statistics of the model if checked or unchecked. It is simply for visualization. Rotate while traveling : If this box is checked, the Staff resource will rotate as needed in order to orient itself in the direction of travel. If the box is not checked, it will always face the same direction. This option will not affect the statistics of the model if checked or unchecked. It is simply for visualization. Travel offsets for load/unload tasks : This box provides 3 options. If "Travel offsets for load/unload tasks" is selected, the Staff will be move to the exact point where the patient or item is being picked up or dropped off. If "Do not travel offsets for load/unload tasks", it will travel to the origin of the destination object and pick up or drop off the patient or item there. In the case where the Staff is using network nodes to travel to the destination, it will travel to the network node attached to the destination object and then stop there. The option "Do not travel offsets and block space on network" only applies when the resource is connected to a network of nonpassing paths. If it is chosen, then the resource will arrive at the node, finish its travel, and while it is doing the load/unload operation, it will continue to take up space on the network, and block other objects traveling on the path. Load time:This pick list returns how long it takes this Staff resource to load an item or patient. Unload time : This pick list returns how long it takes this Staff to unload an item or patient. Break to Requirement : This field is executed when the Staff comes to a break task or callsubtasks task. The return value is a reference to a task sequence. The logic within this field should search the Staff's task sequence queue, and find a task sequence that is appropriate to break to. Dispatcher Pass To:This pick list returns the output port number that the task sequence should be dispatched to. If 0 is returned, then the task sequence will be queued up using the below mentioned queue strategy, and then will be dispatched to the first available resource. If :1 is returned, then the Dispatcher will do absolutely nothing. In such a case you would use the movetasksequence() and dispatchtasksequence() commands to execute dispatching logic yourself. See Pass To pick list. Dispatcher Queue Strategy : This pick list returns a "priority" value for the task sequence that is used to rank it in the resources task sequence queue. By default, it will simply return the priority value given to the task sequence when it was created, but the user can also customize task sequence priorities in this field. See Queue Strategy pick list.

Modeling Tools
1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. Flowcharting Path Creation Global Variables Global Process The Experimenter Animation Creator AVI Maker Flowitem Bin Global Tables Shift Schedules User Events Import Media Files Model Triggers Random Interrupts Excel Table Import/Export Presentation Builder Script Editor Event List Event Log Step Debugging User Commands

The Animation Creator


The Animator allows you to create and save custom animations for FlexSim objects in your model. In FlexSim, animations are made up of Keyframes. To create/edit an animation, double-click on any object to open its Properties window, click the General tab, and click the Edit button under Visuals/Animations.

This will open the Animation Creator. The Animation Creator allows you to edit existing animations, create new animations, and preview your animations.

Creating an Animation
As an example, we will create a simple animation for an operator that he will use while processing an item at a Processor.

Step 1
Create an Operator and open the Animation Creator by clicking the General tab, then click Edit in the Visuals/Animations section. Create a new animation by clicking the button. Make sure you click the button that's below the Animation Pane, not the one at the top of the window.

You can name the animation by clicking the text of the drop-down list and entering your own. You now have a "blank slate" on which you can create a new animation, customized to your needs. To keep things simple, you are going to create an animation with only 3 keyframes and some very simple arm movement so that you can learn the basics of the Animation Creator. If you take a look at the top of the window, you will the see the tree view for the sub-objects that make up the operator. Objects that are inside

other objects (indicated by an indentation) are subject to changes made to their owner object. For example, click LArm, then click and drag in on of the view to move it, or change the X, Y, or Z values on the left side of the window, and you will see that the LForearm and the LHand move along with the LArm. The same is true for rotating and scaling, though there are some different options for scaling that I will discuss later. When making changes to objects in the Animaiton Creator, it is usually wise to start from the outside; if the Operator's whole arm is going to change positions, start with the arm, then the forearm, then the hand. Before we move on, if you have messed up how your Operator looks, click the Go To Base Positions at the top of the window to revert to the normal standing operator.

Step 2
Click the button to make sure that you are working at the beginning of the timeline. Click LForearm in the tree, and change RX to -90. Do the same to the RForearm.

Click LHand in the tree, and change RZ to 0. Change the RHand RZ to -90. He now has both arms out, with his palms facing down. This will be our starting position.

Click Add Keyframe to make this the position at time 0.

Step 3
You will now add the rest of the animation. Make sure that you change the timeline BEFORE you start editing the animation. clicking the timeline will show the

animation that is currently at that time. Click the timeline at about 2.0. In the default view, each tick mark represent .5 time. Now you are editing the animation at time 2, and you can make some changes to animate the Operator. Click LForearm, and change the RZ to 35, and the RX to -75. Do the same with RForearm, but change RZ to -35.

Click Add Keyframe to add this position to time 2 on the timeline.

Step 4
You will now add the final keyframe in the animation, which will look the same as the first keyframe. This is done so that the animaiton is "seamless," or so that the animation looks smooth Click the timeline at about time 4. Click LForearm, and change the RZ to 0, and the RX to -90. Do the same for RForearm.

click Add Keyframe to add this position to time 4 on the timeline.

You can now preview the animation by clicking the

button.

Step 5

Now you can define some parameters. Change the name of the Animation to something you can remember, and notice also the rank of the animation in the list. These will both be important for using the animation in the model.

Implementing the Animation in Your Model


To run an animation in your model, you use the startanimation() and stopanimation() commands. Add these commands to triggers in your model when you want to start and stop the animation. For more information on this, refer to the command documentation for startanimation() and stopanimation().

AVI Maker
The AVIMaker is created when the AVI Maker option is selected in the Tools > Presentation menu. It is a special object in the model that calls the commands to make an AVI file of the model running. It will make this file as long as it is in the model. If the user does not want to make the AVI file, they need to delete the object from the model. Before running the model, the user must designate a view to record. This is done by right-clicking on the view they want to record and selecting View | Designate this View (sv). The model may run very slowly while the AVI file is being recorded. It will not respond to the speed slider bar in the run control window during that time.

AVI Name - This is the name of the file that the AVIMaker will write to. It should have an .avi extension. Starting Time - This is the time that the AVIMaker should start recording the AVI file. Ending Time - This is the time that the AVIMaker will stop recording the AVI file. It is recommended that the model not be stopped before this time, as it may corrupt the file being written to. Time between frames - This is how much simulation time passes in the model between recorded frames. Frames per second - This number defines how many frames per second the AVI file plays back at. Run Fly Path - If you have created a fly path in your model you can select that fly

path in this drop down box. The view will follow that fly path as the model runs, giving more interest to the recorded avi. Delete AVIMaker - When this button is pressed, the AVIMaker is deleted from the model. The model will run at normal speed again, and the AVI file will not be generated.

Step by Step: Properly working with the AVI Maker


The AVI maker can often be tricky to work with. Here are steps to go through to make sure that your AVI is created with as little hassle as possible. 1. If there is already an AVI Maker in the model, delete it by pressing the Delete AVIMaker button. 2. Compile the model if necessary. 3. Re-open the AVI Maker window. 4. Fill in the above mentioned fields appropriately. a. Make sure the name of the avi file is not the name of a file that already exists. b. Set the start and stop times according to the simulation time that you want the avi to be recorded during. c. Set the frames per second value to whatever you want your avi playback speed to be. 10 frames per second is usually reasonable. d. Set the time between frames value based on the frames per second value you specified. Find an ideal run speed that you want the avi to record for the model (from the simulation run control panel). The time between frames should be calculated as that ideal run speed divided by the frames per second Right click in the 3D view you want to be recorded and select View > Designate This View (sv) Resize the 3D view to the resolution you want for the avi movie. Setting a smaller window size can dramatically increase the speed that the avi maker can create the movie. Reset and run the model A window will pop up about the codec to use. Enter the codec/compression that you want to use. IMPORTANT: Wait until the avi maker is finished. Once the model gets to the avi's starting time, do not press any buttons or click on anything until the model time is past the ending time you have specified for the avi maker. Once the model has run past the avi maker's ending time, stop the model. Do not hit reset again until you have deleted the AVI Maker. Delete the avi maker using the Delete AVIMaker button.

5. 6. 7. 8. 9. 10. 11.

The Dashboard

General
The Dashboard window allows you to view graphs and statistics for the model as it runs. It is especially useful for comparing objects side by side. It can be opened by clicking the Dashboard button in the toolbar: . You may save Dashboard templates with the Save button for use in future models. The Open button loads a saved Dashboard intp this window.

Adding Graphs
1. Select a Graph Type : Text Panel : Pie Chart : Bar Graph : Stacked Bar Chart : Model Control/Custom : Line Graph

2. Choose a Statistic Choose one of the options from the button's menu. This statistic will be displayed for every object on the graph. 3. Reset and Run the Model The new graph will be blank until the model runs. Some Graphs will begin updating as soon as the model starts but others, such as those that gather data on Patients will update upon the first pateint leaving the model

Working With Graphs


Editing - Double-click the graph to open its properties window. The type of properties window that opens will depend on the type of graph that is being selected. Moving - Click the graph, then drag it by the cross-hair cursor icon.. Resizing - Click the graph, then drag from any border. Context Menu - Right-click the graph to open its context menu.

Edit Graph Settings - This option opens the graph settings window. View Graph Data- This option will give you access to the raw data collected by the graph so far Delete Graph - This option deletes the graph from the Dashboard.

Tabs
Adding Tabs - Click the button to add a tab.

Context Menu - Right-click anywhere empty on a tab to bring up its context menu.

Add Tab - This option adds a tab to the Dashboard. Edit Tab Name - This option allows you to change the name of the tab. Delete Tab - This option deletes the selected tab.

Graph Types
With each of the different chart types, the best way to get familiar with what information they give you access to to is to experiment and try them out. Each chart option also has a user defined option for advanced users to make their own custom charts if desired.

Examples
Text Panel (Predefined Simulation Variable)

Bar Graph (Milestone Completion Times)

Pie Chart (State Pie)

Line Graph (Content vs Time)

Event List Viewer


The Event List is accessed from the Debuggging menu option under Tools. It shows all the pending events for the model. It is useful for seeing when different events will occur and debugging modelling issues. If you have a problem that happens during a particular event, the Event List is useful for seeing information about that event to help track down the source of the problem.

Time - This is the time that the event will occur. Object - This is the path to the object that the event will fire on. Event Type - This is the type of event. It is the event code and will show a number value for event codes without registered names. You can use the "seteventlistlegendentry" application command to register a name for custom event types. For example: applicationcommand("seteventlistlegendentry", 102, "My Event Type", 0); will set event code 102 to show "My Event Type" as its name in the list. Involved - This is the path to the involved object for the event. Event Data - This value's use depends on the event and may not be used for all event types.

Filtering
The Time, Object, and Involved columns can be filtered by clicking on the column header.

Time - You can add multiple ranges of time to display. Object and Involved - You can select various objects in the model to display or not.

Event Log
The Event Log is accessed from the Debug menu. When enabled, it will create a record when certain events occur in the model. It is useful for seeing the order in which certain events took place in the model. For each event that happens in the model, multiple entries may be made in the Event Log to explain what happened during that event. These multiple entries will all have the same time and all be logged simultaneously when you press the Step button. The event log will be cleared when the model is reset. Some exceptions will be recorded in the event log. The entry immediately preceeding the exception entry will give you a clue as to where the code is that caused the exception to happen. This is particularly useful if the exception was caused by improper code in an object's trigger. More information about the exception may be available in the System Console. The model may not be behaving correctly if there are exceptions happening in the code.

Enable Logging - This will enable or disable event logging. The model will run much slower when logging is enabled so you should disable logging when you are finished using the event log. Start Time - If you only want to log a specific time period, you can enter a start time for when the logging should begin. This will automatically apply after editing this field without having to reset and rerun the model. End Time - Optionally, you can specify an end time for when you want the logging to stop. If the end time is less than or equal to the start time, it will be ignored. Settings - Within the settings window, you can set up which events should be recorded in the event log. Events that have already been recorded will not be affected by changing these settings, but events that occur after changing these settings will only be recorded if they are enabled here. Export - This will export the Event Log as a csv file. It will export what you can see in the table; any entries that have been filtered out will not be exported.

The Table
Time - This is the time that the event happened. The entries happened in order from top to bottom. Entries recorded with the same time happened in the order shown and may have happened during the same model event. Event - This is the type of event. You can enable or disable logging for certain event types in the Settings window. Object - This is the path to the event's object. Involved - This is the path to the involved object for the event. P1 - P4 - These values depend on the event and may not be used for all event types. Usually they give you information about what parameters were passed into the event or more information about the event type. This is useful for debugging if parameter values are not what you expect them to be.

Filtering
The Time, Event, Object, and Involved columns can be filtered by clicking on the column header. Event log entries that are no longer displayed because they have been filtered will not be exported with the Export button.

Time - You can add multiple ranges of time to display. Event - You can select various event types to display in the list. The filter list will only display event types that have been recorded. Object and Involved - You can select various paths that have been recorded to display or not. The filter list will only display paths that have been recorded.

Working With Excel

Table Import:Press the Table Import button to import single or multiple tables into FlexSim Healthcare. To configure these tables, press the edit button to bring up the Excel Import editor. Table Export: Press the Single Table Export button to export the configured table from FlexSim Healthcare to Microsoft Excel. To configure this table, press the edit button to bring up the Table Export editor. Custom Import:Click on the Custom Import button to import from excel using your own custom code. To write and edit this custom code, press the edit button to bring up a code editor. Once you have edited this code, you will need to compile before being able to import from Excel.

Custom Export: Click on the Custom Export button to export to excel using your own custom code. To write and edit this custom code, press the edit button to bring up a code editor. Once you have edited this code, you will need to compile before being able to export to Excel.

Flowcharting
The Flowcharting tool, accessible via the button in the tool bar, is designed to help you with better organizing and understanding your patient flow. It has the added ability to help manage and create the necessary object connections. Object connections are an important part of making your model function properly. These connections allow patients to enter and exit the objects and move on to whatever destination the track may dictate. It may be helpful to think of these object connections as relationships between objects that patients use in order to follow their track activities. The Flowcharting view of the model allows you to more easily manage and organize these relationships.

In this view you will see all of the Areas in your model represented as colored rectangles. You may organize the arrangement of these representations however you like, as their positioning in this view does not change how they are arranged in the actual 3D model view. By default, they will be arranged from left to right in the order that the Area was created. Positioning the cursor over the left hand side of the window will expose the options available for this view. Here you may chose to move the Area representations, connect them together or disconnect them. In order to connect the Area representations together, simply click on the origin Area and then click on the destination area. A connecting line will be drawn between the two representations with an arrow head indicating the direction of patient flow. You may attach a name to a connection line as well as change it's color for increased organization and clarity. Using different colored lines for area connections is just for organization purposes, and has no inherent meaning. The connections between actual locations within the model are made based upon the area connections of all the colors defined (care is taken that location connections are not duplicated when the same two areas happen to be connected in different colors). One idea for using different colored connections would be to make the connections associated with going to and from the waiting room in a different color than the connections that are required in order to satisfy the Next Area explicitly specified in the patient transfer activities of the tracks. The Auto Connect feature has the ability to automatically make object connections for you. It does this based on information in your tracks, and so it is limited in effectiveness to very simple models. If your model has no tracks, this button will do nothing. The Auto Arrange button restores the Area representations to their default arrangement. You may remove all connections between the Areas with the Remove Connections button. This would accomplish the same end as choosing the Disconnect mode radio button, but all at once, rather than removing individual connections. The Display Location checkbox will toggle display of the names of the locations that are members of the given Areas.

In the above example, notice that patients who need to use the WaitingRoomArea if triage is not available, there must be a connection from the WaitingRoomArea to Triage. Also note the bidirectional arrow on the connection between the WaitingRoomArea and the TriageArea. This means that patients may travel from the WaitingRoomArea to the TriageArea or vice versa. If you were to create a track where such a movement was needed you would need to make a connection to allow it. If no connection exists between two areas, patients cannot move there, so be sure to double check your connections first if patients seem unable to go to a destination defined for them in an activity.

FlowItem Bin
Items
Items are the simple objects that are created to move through the model. They can represent actual objects, such as lab samples or paper work, or they can be representative of a more abstract concept. Different classes of items are created in this window and are stored in the Flowitem Bin. The editor is opened by pressing the button on the FlexSim Healthcare Toolbar.

Flowitem List - This list contains all of the available flowitem types. When one is selected, it is shown in the main window. You can edit the properties of the flowitem such as name, shape, and size by selecting the flowitem in this list, then pressing the Properties button. New Item - This button adds a new flowitem to the bin. The new flowitem is a copy of the currently selected item in the flowitem list. Delete Item - This button deletes the currently selected flowitem from the bin. It can no longer be created in the model. Properties - This button opens the currently selected flowitem's Properties window.

Global Process
Global Process are very similar in structure and behavior to the Activities you will define for a patient via the Track Manager. The difference being that these activities do NOT involve patients.

Global Process were implemented so that you can generate activities for resources and equipment without the involvement of a patient. All the activities in the Track Manager happen because a patient made requests that must be fulfilled. Global Process have no patient attached, but they still allow you to manipulate staff, transports and equipment. Global Process start the same way patient activities start, according to their predecessors, Start Time and Activity Start Condition. You can also start them with code, using the startactivity() function (more information is available in the Scripting help from FlexSim Healthcare' Help menu). Since these activities do not have an involved patient, there are no activity types that deal directly with patients. No escorting, no transporting, etc. These are meant to deal with things that may happen regardless of the presence of a patient, even the lack of one. Since the Global Process List and the Patient Track use the same activity types, minus Escort Patient > Process, Transport Patient > Process and Patient Travels Unattended, you may refer to the explanations for these types under the Track Manager topic

Global Tables
These objects are not dragged out into the model. They are created through special dialog boxes that are reached through the toolbars. Global tables are accessed through the Tools menu. They can store numeric or string data. This data can be accessed by any object in the model using the gettablenum(), gettablestr(), settablenum(), settablestr(), reftable() commands. For more information on these commands, refer to the command summary. A model may have any number of Global Tables.

Name- This is the tables name. It should be memorable and describe the tables function. The commands to read and write to them access them by name. Be sure to press "Apply" after changing the name of the table. You can view other Global Tables in this window by clicking the dropdown arrow next to the name. Add a table -This adds another Global Table to your model. Delete this table - This deletes the currently selected Global Table from your model. Rows - This is the number of rows in the table. After changing it, press Apply to update the table on-screen. Any new rows that were created can now be edited. Columns - This is the number of columns in the table. After changing it, press Apply to update the table on-screen. Any new columns that were created can now be edited. Reset - If this box is checked, all number cells in the table will be set to 0 when the model is reset.

Editing the Table


To edit a cell in the table, double click on the cell and type the data in the cell. If you click a cell and begin typing, it will overwrite any data that is currently in that cell. Press the arrow keys to navigate between cells. Cells hold numbers by default, but can be set to hold string data by rightclicking on the cell and selecting Assign String Data.

Global Variables
The Global Variables window lets you create global variables that are accessible in Flexscript as well as macro definitions. These variables are useful anytime you have a value or object reference that you wish to be made available globally to any event or object in the model.

Press the Add or Remove buttons to add and remove global variables. Then select the variable you would like to edit, and specify the name, variable type, and initial value(s) in the panel on the right. There are 8 variable types you can use: integer, double, treenode, string, integer array, double array, treenode array, and string array. For the array types, you can specify the size of the array and the initial value of each array element. Note: The value shown is the initial value of the variable. It is not the current value of the variable. The current value of the variable is stored in memory and can be seen by returning it in a script console or otherwise printing it from code. The current value is not stored in the tree anywhere. The initial values are reset when you open the model or compile. They are not reset when you reset the model. Once you have specified global variables, you can get and set the values of the global variables with Flexscript code.

Global Macros
The global macros page lets you make macro definitions. You do this by using #define statements, as follows: #define MACRO_VAL 5 #define BLAHBLAHBLAH 6 #define SOME_DESCRIPTIVE_NAME gettablenum("GlobalTable1",1,1) Once you have made these definitions, you can use them in your code. Note: Macro definitions do not end with a semicolon. If you put a semicolon in the macro definition, it may do things you don't expect it to do. Macros essentially replace the given text with the following specified text throughout your code. If you have a semicolon at the end of the statement, you may end up with semicolons in incorrect places in your code.

Modeling Tools
1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. Flowcharting Path Creation Global Variables Global Process The Experimenter Animation Creator AVI Maker Flowitem Bin Global Tables Shift Schedules User Events Import Media Files Model Triggers Random Interrupts Excel Table Import/Export Presentation Builder Script Editor Event List Event Log Step Debugging User Commands

Model Triggers
Model Triggers can be accessed through the Tools menu. The model triggers allow you to execute code at different points between model runs. The available triggers are:

On Model Open - This trigger is fired when the model is opened from the file. On Reset - This trigger is fired when the model is reset. On Run Start - This trigger is fired whenever the model changes from a stopped or paused state to a running state. On Run Stop - This trigger is fired whenever the model changes from a running state to a stopped or paused state. On Post Compile - This trigger is fired after the completion of a compile.

Random Interrupt Editor


Interrupt objects are accessed in the Tools menu. They are used to set random breakdown and recovery times for groups of objects in the model. these types of interrupts are used to model some kind of random occurrence that might effect staff resources or locations in the model. They are independent of track activities and Shift Schedules. An Interrupt object can have multiple members objects attached to it. Each object can be controlled by more than one Interrupt object. The Interrupt object allows you to also specify what state the objects will go into when they are interrupted. A model may contain any number of Interrupt objects. The Interrupt window is split into three tab pages.

Name - The name of the Interrupt object. This should be something descriptive and easy to remember. For example, Injury or Random Inspection.

Member List Page

In this page you can specify the list of member objects for this Interrupt object. The panel on the left is a list of model objects. The panel on the right is a list of the members of this Interrupt object. Select objects from the left panel and click the button to add the objects to the member list. Select members in the right panel and click the button to remove them from the list.

Definition Page
In this page you can specify the times to go down and resume, down and resume

triggers, as well as the down and resume functions.

First Interrupt Time - This pick list returns the time of the first interrupt. See the time pick list. Interrupt Interval (MTBF) - This pick list returns the Mean Time Between Failure for the objects controlled by this Interrupt object. This function determines how long those objects will run before they go into a broken-down state. The MTBF time is specifically defined as the span between the time that the object resumes from its last down period and the time that it starts its next down period. See the time pick list. Interrupt Duration (MTTR) - This pick list returns the Mean Time To Repair for the objects controlled by this Interrupt object. This function determines how long they will stay in a down state before resuming normal operations again. All of the controlled objects will go back to their original states at the same time. See the time

pick list. Interrupt Function - This pick list is executed when the objects in the member list go down. It is executed once for each object in the member list. Here is where you specify what to do to stop the object. Resume Function - The pick list is executed when the objects in the member list resume their operation. It is executed once for each object in the member list. Here is where you specify what to do to resume the object. Start Trigger - This pick list is fired immediately after the Down Function, but it is only executed once, instead of once for each object in the member list. See Down/Resume Trigger. Finish Trigger - This pick list is fired immediately after the Resume Function, but it is only executed once, instead of once for each object in the member list. See Down/Resume Trigger.

Advanced Page
The breakdowns page let's you configure more details of how the objects will be broken down.

Down State - This specifies the state that the object will go into when it goes down. Break down members individually - If this box is checked, the Interrupt object will create a separate thread of down and resume events for each member object. If it is not checked, all member objects will go down and resume at the same time. Apply MTBF to a set of states - This box only applies if the Interrupt breaks down members individually. If it is checked, then the MTBF time will only be applied to a subset of the object's state. For example, if machine break down data only applies for when the machine is actively processing, then you would use this field. If checked, you will add a set of states to the list on the right from the list of possible states on the left. Accuracy - This field only applies if the Interrupt uses a subset of the objects' states for its MTBF time. Usually this value will be 100, or 100% accuracy. However, if the

subset of states represents a very small portion of the total time of the member objects' state times, then the accuracy value can be used to optimize for run speed. For example, if an MTBF is applies to an object's "Waiting for Operator" state, but the object is only in that state 5% of the time, an accuracy value of 100 would cause the MTBF to perform several checks before bringing the object down. If you then change the accuracy value to 5, then the MTBF will probably need to do much fewer checks before bringing the object down. Range Cutoff - This field only applies if the Interrupt uses a subset of the objects' states for its MTBF time. Usually this value will be 0. However, if the subset of states represents a very small portion of the total time of the member objects' state times, then the range cut-off value can be used in conjunction with the accuracy value to improve run speed. This specifies a range within which the MTBF can go ahead an bring the object down. For example, if the next down is scheduled for when the object's subset of states has reached 10000, and the range cutoff is 100, the MTBF will do a check, and if the state subset is above 9900, it will go ahead and bring the object down.

Table Excel Import/Export

Overview
The Excel Table Import/Export was designed to make importing or exporting multiple worksheets from more than one workbook very fast and easy to do. The interface is capable of automating much of the import process in terms of the table size and cell data type. If you allow the feature to be more automatic in its implementation it is extremely useful for importing data that will change over time. Many of the objects in FlexSim use tabular data in order to implement their functionality, such as the Patient Arrival objects. This interface, allows you to import into these internal tables as well as Global Tables, as well export to external files.

Setting up the Interface for Import


The first thing to notice about the Table Import interface is that you can define as many individual imports/exports as you wish by clicking the Add button at the top. Each entry in the list is an individual table that you may import/export or both that will all be done together as a group. Highlighting the listing on the left will show you the properties that define it. Title: Here you may assign a name for this action. This name is merely for your convenience and doesn't effect how the import will behave. Table Type: use this drop down to chose what type of table within FlexSim you will be importing to, or exporting from. You may chose a Global Table, any arrival table located within a Patient Arrivals Object. More advanced users may wish to use the Object Table option available from the dropdown menu. From there, you may browse to any table node located within the FlexSim Health Care tree structure. Import/Export Check Boxes: These checkboxes allow you to designate whether this will be a table that you export to or import from, or both.

Table: Choose the FlexSim table that will serve as the destination for imported data, or the source for exported data. Pre-Export Trigger: This trigger will fire before the tables exported. You may write any custom code you wish for this field, to be executed before the export procedure begins. Post-Import Trigger: This trigger will fire after all tables have been imported. You may write any custom code you wish for this field, to be executed after the import operations complete. Start Import: This button starts the import process, the user will be prompted to browse for the Excel workbook to import data from. Start Export: This button starts the export process, the user will be prompted to browse for the Excel workbook to export data to.

OptQuest Optimizer
The OptQuest optimizer lets you optimize variables in your model to maximize certain output variables.

Decision Variables
The first part of designing an optimization is to define the decision variables for the model. The main decision variables for an optimization can usually be chosen by restating the problem you want to solve. For example, one problem may be: how many machines do we need in this area to get the best throughput? This statement defines the decision variables for the model: the maximum content value of the processor, and the throughput value of the model. Note that these two variables have different roles. The maximum content is a value we want to change and experiment with, while the throughput is our feedback, reflecting the results of our changes. To add a decision variable, click on the Add button in the Variables panel. This adds a new variable to the variables table. Select this variable by selecting any cell on the row of the new variable, then click the Modify button. This brings up a window to edit this new variable.

Each decision variable has an associated name, which will be used by OptQuest. Each variable also has an associated type, like continuous, integer, or user-controlled. User-controlled variables are the "feedback" variables. They are not changed by the OptQuest experimentation, but are used as output variables to get feedback for how well different scenarios do. All other variable types will be changed and experimented with during the optimization. Once you have specified the variable name and type, click on the Browse button to associate this variable with a node in the model. This will

open a Tree Browse window to select the node that holds this maximum content value. You must select a node that has number data on it, or the optimization will not work properly.

Constraints
Once you have defined your decision variables, you will want to define constraints for the optimization. During the optimization, the optimizer will try several scenarios on the decision variables. Constraints are used to nullify certain scenarios if these constraints are not properly met, so that the optimizer doesn't choose an invalid scenario as the optimum. Each constraint has an expression, such as "MaxNrofProcessors < NrofProcessorsUsed + 5". To add a constraint, press the Add button, and then fill in the equations column.

Objective Function
The objective function is an expression that you want to maximize or minimize. This could be a simple expression like "Throughput" if you have a decision variable called Throughput. It could also be a revenue vs. cost estimation. For example, if each product produced yields $5.00, and the cost for each machine (weighted by the length of the simulation run) is $50, then the objective function could be "(Throughput*5.00) (MaxNrofProcessors*50.00)".

Stop Conditions
Maximum Time for Optimization - This is the maximum real time that the optimizer will spend in its optimization. AutoStop - If this box is checked, the optimization stops when the value of the objective function stops improving. The FlexSim current setting is to stop when the objective function value of the best solution found does not vary by at least 0.0001 after 100 iterations.

Scenarios
Maximum Scenarios - This is the maximum number of different scenarios that the optimizer will try. A scenario is one configuration in the optimizer's search. Current Scenario - This is the current scenario number being tested. Current Solution - This is the value of the objective function for the current scenario. Best Solution - This is the value of the object function for the best scenario so far.

Simulation Time per Scenario/Real Time per Scenario - This is the maximum simulation time that the optimizer will spend for each scenario. The optimizer stops a scenario as soon as this is met.

Replications
If you want to run the simulation several times for a given scenario to increase confidence of the mean of the objective function, use the Replications panel to specify how many replications to run.

Perform Multiple Replications per Scenario - If this box is checked, the optimizer will perform more that one replication per scenario. Minimum number of replications - This is the minimum number of replications to run for each scenario. If there is no Early Exit Criterion then the optimizer will always run the minimum number of replications. Maximum number of replications - This is the maximum number of replications to run for each scenario. If there is an Early Exit Criterion then the optimizer will run the scenario until the criterion is met, up to this maximum number, after which the optimizer will stop the scenario. Early Exit Criterion - This allows the optimizer to stop running further replications for the same scenario, based on the criteria you select. If you've selected "Confidence Interval Satisfied" the optimizer will stop replications once it can determine the objective function's true mean for the scenario with the given confidence and error percentages. For example if you specify an 80% confidence and a 5% error, then the optimizer will stop running replications as soon as it is 80% confident that the true mean of the objective function is within 5% of the mean sampled. If "Best Solution Outside Confidence" is chosen, then the optimizer will stop replications for a given scenario if it can determine, within the given confidence and allowable error percentages, that the best solution can never be met with this scenario.

Optimizing
Once you have configured the above parameters, press the Apply button to apply your configuration, then press the Optimize button, and wait until a message appears telling you that the optimization has finished. Note: If you have C++ code, make sure your model is compiled before clicking the Optimize button, or else FlexSim may freeze operation. Note: Once you have clicked the Optimize button, don't do anything until the optimization has finished.

Statistical Output
The Statistical Output tool is used to customize which model data will be reported.

Output Data
This section allows you to save the raw data of the model to an external file if you choose, and to select which data will be exported. By default all of the boxes are unchecked due to the overhead performance costs of collecting statistics. Once checked, the applicable information will be written to a delimited text file. State history is recorded at every time interval using the Time Interval you specify, and Patient History is recorded when a patient leaves the model. Because of the performance costs of recording statistics, it is recommended that you only check those data items that are absolutely necessary. Output File Name: This allows you to edit the name of the file. The file extension (.txt) will be added automatically and a number will be appended to the end of the name so that FlexSim Healthcare will not overwrite a file that has been generated. These numbers will be in the form myFile_#, where # is one greater than the last. If none exist, it will create myFile_1, and go up from there.

Output Directory:This allows you to edit the directory the data file will be saved to. Data Delimiter:This allows you to change what will delimit the data. State History:You can select which statistics are recorded to output by checking or unchecking each option. State History will create up to eight files depending on which checkboxes you have selected. Each of the checkboxes represent a different file. Each row in the files is corresponds to an interval of time you may specify using the Time Interval parameter. The columns in each table are as follows: 1. Patient Queuing Locations 1. Name 2. Area 3. Queue 4. Average Queue 5. Maximum Queue 6. Average Staytime 7. Maximum Staytime 8. Throughput 9. State Durations 2. Patient Processing Locations 1. Name 2. Area 3. Queue 4. Average Queue 5. Average Staytime 6. Maximum Staytime 7. Throughput 3. Item Queuing locations 1. Name 2. Area 3. Queue 4. Average Queue 5. Maximum Queue 6. Average Staytime 7. Maximum Staytime 8. Throughput 9. Empty Time 10. State Durations 4. Item Processing Locations 1. 2. 3. 4. 5. Name Area Queue Average Queue Maximum Queue

6. 7. 8. 9. 5. Staff

Average Staytime Maximum Staytime Throughput Processing time

1. Name 2. Group 3. Skill Level 4. Pay Rate 5. State Durations 6. Equipment 1. Name 2. Group 3. Skill Level 4. Pay Rate 5. State Durations 7. Transports 1. 2. 3. 4. 5. 8. Totals 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. Name Group Skill Level Pay Rate State Durations Total Throughput Hourly Throughput Staffing Cost Procedural Cost Total Cost Cost Per Patient Length of Stay (LOS) Left Without Being Seen (LWBS) Total Occupancy Occupancy by Track

Patient History: You can select which statistics are recorded to output by checking or unchecking each option. Recording these statistics will create a ninth file, where each checkbox is a column in the file. Rows are represented by each individual patient that come into the model. Checking the Record checkbox for the Activities group will append the associated checkboxes as additional rows tot he Patient history file.

Path Creation
Walking paths are an aid to your model that allow you to designate valid paths that Patients, Staff and Transport resources will use when executing a travel activity. With no Paths available, these mobile resources will walk in a simple shortest distance between two points manner. Adding paths adds extra, more realistic behavior to your model. To create Paths, click the Path button: from the object library. Now when you click in the model view you will create a Node on the path. Multiple Nodes in the model will automatically link up upon creation in order to form a Path. These Paths form a dark line connecting the nodes with two green boxes about one third the distances from the end point Nodes. The green boxes indicate that the Paths allow for bi-directional travel and allow for traffic on the node to pass each other. Double-Clicking the direction indicator brings up a contextual menu that allows you to select ways to modify this behavior. This menu will also allow you to choose whether the path is a straight line or curved. When Paths are curved, the paths gain two extra black squares near the center of the path. These squares are called Spline Points that you may click and drag to adjust the curvature of the Path. Once the Path is laid out as you wish, you must make quick associations between the path and resources that may be visited by travelers on the Path. To accomplish this, simply click on a Node on the Path closest to the resource and then click the resource itself. The association is represented by a blue line from the Node to the object. Once the associations are made, you can then tell the traveling resources (Staffs, Transports, etc) to use Paths. Go to the properties for the Staff resource, and check the check box marked Connect to Walking Path. Members of that staff group will now automatically find the nearest node to a path and use it for all travel activities. See the Paths Tutorials for more detailed information

Presentation Builder
The presentation builder is a special perspective view that will assist you in developing a fly-thru presentation of the model. The presentation builder is displayed when you select the Presentation Builder option in the Presentation menu. This panel is used to create and edit fly paths.

A FlexSim presentation is simply a series of fly paths. Each fly path is made up of a set of view points, or fly points. Flying through a given fly path means that the perspective view sequentially flies to each fly point in the fly path. A presentation is an ordered series of fly paths.

Presentation Edit Panel


The presentation edit panel allows you to create, edit and run fly paths. It is made up of several control panels from which you can configure your presentation.

Fly Paths Panel


The fly paths panel allows you to edit all fly paths. Click on the New Fly Path button to create a new fly path. The presentation view's current viewpoint will be set as the first point of the fly path. Click on the Delete Fly Path to delete the currently selected fly path. To select a fly path to edit, either click on the right or left arrow buttons, or select the appropriate fly path from the drop-down list.

Fly Points Panel


This points panel allows you to edit individual view points in a fly path. Click the New Fly Point button to add the presentation view's current viewpoint to the fly path. Click on the Update Point button to change the currently selected point to the presentation view's current viewpoint. Click the Delete Fly Point button to delete the currently selected point. To select a point, either click the right or left arrow buttons, or select the point from the drop-down list. You can also specify the time that it takes to fly to that point by using the up and down arrow buttons beside the Time field.

Run Control Panel


The run control panel lets you test fly paths that you have created. Click the Run button to repeatedly fly through the currently selected fly path. Click the Step button to step to the next fly point in the fly path. Click the Test button to fly through the currently selected fly path once. Click the Stop button to stop the current fly through. By default the edit panel is sized so that it doesn't take up much desktop space. You can expand it to edit more options.

Sounds Panel
Here you can specify sounds to be played and the beginning and end of a fly path's fly-through. Click the "..." button to browse for a .wav file to play when the fly path is being run. The "Start" file will be played at the very beginning of the fly path run, and the "Finish" file will be played as soon as the fly path finishes.

Fly Path Data Table


The fly path data table allows you explicitly enter data for the fly points of the current fly path. You will usually only need to edit the Time column, but you can also edit other values Time - This field specifies the amount of time that it will take to fly to the fly point. If the "Run fly paths in simulation time" checkbox is not checked, then the time field is specified in real time seconds. If the box is checked, then you will need to specify the time in thousands of seconds. For example, if you want the view to fly to the position in 2 simulation seconds

PosX - This field specifies the x location of focus point of the camera. PosY - This field specifies the y location of focus point of the camera. PosZ - This field specifies the distance the camera is away from its focus point RotX - This field specifies the pitch of the camera. RotY - This field specifies the roll of the camera. RotZ - This field specifies the yaw of the camera. Sound - This is a path to a .wav file that will be played when the camera starts to fly to that point. Only the first and last points in a fly path will play this sound file. OnStart - Here you can write flexscript code to be fired when the fly path starts. The OnStart will only be executed for the first point in the path. OnFinish - Here you can write flexscript code to be fired when the fly path finishes. The OnFinish will only be executed for the last point in the path. Check the "Run fly paths in simulation time" checkbox to make the time to fly to a fly path dependent on the simulation time instead of real time.

Navigating Through Fly Paths in the Perspective View


When you are working in the presentation builder perspective view, you can fly through fly paths by pressing keys on the keyboard. Press one of the numbers: 1-9 to run the associated fly path. Press the space bar or the 'N' key, and the view will run the next fly path. Press the 'B' key and the view will go back to the previous fly path.

Script Editor

The script editor allows you to execute flexscript commands to get information from as well as configure your model. Open it by seclecting the main menu option View | Script Window.Type the flexscript code in the main text pane at the top. Click the Execute button to execute the code. The return value of the code will be shown in the pane at the bottom. If your executed script is several lines, you can use the double forward slash '//' to comment certain lines. Note: The return value of the script you execute will only be shown if the last command in the executed script does not have a semi-colon (;) after it.

File Menu
Load Script - This loads a new script from a text file. Save Script As... - This saves the current script as a text file.

Flexscript Step Debugging


How It Works
Within the FlexSim code editor, there is a margin on the left side of the line numbers. By clicking in the margin, you can add a breakpoint to that line of code. The breakpoint will appear as a red oval in the margin. You can delete the breakpoint by clicking the red oval. When a line of code with a breakpoint is executed, FlexSim will enter step-debugging mode. While step-debugging, you will only be able to interact with the code window, not the rest of the program. The code window will change to give you tools for step-debugging as shown. The title bar of the window shows you what code you are viewing.

Next Line - The yellow arrow shows you what line will be executed next. By pushing the Next Line button, that line will be executed and the yellow arrow will move to the next line of code to be executed.

Continue - This will cause the Flexscript execution to continue until it reaches another breakpoint. If the code currently being executed finishes, then it will leave step-debugging mode. Stop - This button does the same thing as the Continue button except that it will stop the model run as well. This is particularly useful if the model is running quickly, as the Continue button may cause FlexSim to re-enter step-debugging mode almost instantly when it continues. Note that any code or breakpoints that will be executed on the current event will keep FlexSim in step-debugging mode. For instance, if you are debugging an object's Send To Port and there is a breakpoint in the same object's OnExit trigger, pressing the Stop button will stop the model from running, continue the Flexscript execution of that event, and then halt the execution at the breakpoint in the OnExit code. You may need to press the Stop button several times to get past all the breakpoints and leave stepdebugging mode. Local Variables - This area shows you the current values of any locally defined variables. As you step through the code, these values will update immediately so you can see what is happening. Often, models may not behave correctly because variables in code are not what they are expected to be. This part of the window allows you to see exactly what the variables are. Watch Variables - This area allows you to specify other variables or expressions that you want to see, such as global variables. By pushing the + button, you can increase the number of lines in the table. The - button will delete the row that was last clicked in the table. You can double-click on a gray area of the table to enter a variable or expression. Its value will be displayed in the white area of the table. This can help explain why certain conditional statements, such as used in "if" statements aren't behaving as expected. It also allows you to see global variables that otherwise are not visible on the Local Variables tab.

Breakpoints
The Breakpoints window is available through the main menu option Debug > Breakpoints. It is a treeview with checkboxes showing you what breakpoints have been added to code in the model. You can disable breakpoints by clicking the checkbox next to the line number where they are. You can disable all the breakpoints by unchecking the "Enable Breakpoint Debugging" box. Checking and unchecking these boxes will only affect whether a breakpoint is enabled or disabled, it will not actually delete the breakpoint. To delete a breakpoint, you can highlight it in this window and press

the delete key or click on its red oval in the code window. Disabled breakpoints will appear as a translucent red oval in the margin and will not cause the Flexscript execution to stop for stepdebugging.

The Experimenter
The experimenter tool can be reached from the Experiment button: from the toolbar. This dialog allows you to run experiments by running your model through multiple scenarios, changing certain variables between model runs, and collecting output data from each scenario. Each scenario represents a certain model configuration. The model runs several replications for each scenario.

Settings
These fields determine how many different scenarios to run, how many replications per scenario, and other model run information Warmup End Time: After the model has run for this amount of time, the statistics are reset, but the model is not. Simulation End Time: After the model has run for this amount of time, the model stops, and the next replication or scenario (if there is one) will be run. The End Time may be superseded by a picklist option on any relevant object in the model. In the "OnEntry" or "OnExit" trigger, the "Stop the Model Run" option can be used to dynamically stop the model run. Number of Replications: This number defines how many replications will be run during each scenario. Save output file for each replication: If this box is checked, the model will save output files for each replication according the settings defined in Output. Replication/Scenario Status: These text displays report the currently executing Replication and Scenario.

Start Experiment:Begins the currently configured Experiment. Suspend Draw: This button allows you to turn off the graphics updating of your model while the experiment is running. Choosing this options increases performance.

Variables
This table allows you to define the configuration for each scenario in the experiment. An experiment variable is value or setting in the model you want to experiment with. For example it may be the number of available locations within an area, or the number of Staff available within a resource group. You may define several experiment variables for your experiment. Each experiment variable is associated with a row in the table. Enter the number of experiment variables you would like to use, then press Apply, and the appropriate number of rows will be created. Number of variables: This field adds rows to the variables table, and allows you to specify how many variables to track for a given Replication, and what values they will have for each Scenario. Number of Scenarios: This number defines how many scenarios will be run. Each scenario may have multiple replications in it. The number of scenarios is defined in the Number of Scenarios field. A special event is called at the end of each scenario. The scenarios are represented as columns in the variables table. Values and expressions for each cell denote the value of the given variable for that Scenario. Current Replication: This number is the number of the replication that is currently running. The replication numbers start over for each scenario. Current Scenario: This number is the number of the scenario that is currently running.

Specifying the experiment variables


To choose a variable, click the cell under the Experiment Variable column of the table and select from the list:

Once you have selected the desired variable you can give it a custom name, and select the group or resource that the variable will be tied to.

Once you have selected an experiment variable, fill in the value that you want the variable to be set to for each scenario. Each scenario value is associated with the variable row in the table.

Performance Measures
The performance measures tab page lets you specify the output measures to evaluate for each scenario.

To add a new performance measure, click on the "Add" button. To edit a performance measure make sure it highlighted in the list. Then give the performance measure a name and define what you are measuring using the pick list. At the end of each replication the measure functions are executed and recorded. Once the whole experiment has finished, you can click on the "View Results" button to bring up a window showing the results of each of the performance measurements.

The above performance measure results show the Length of Stay for patients in a clinic where there are 1, 2 or 3 Physicians available to treat them. Notice that two doctors is an improvment over one, but three doesn't seem to greatly impact how long a patient is in the clinic compared to two. In addition to this view, you can also view the detailed results in table format by pressing the "View Table" button. By pressing "Generate Experiment Report" an html document is created for you showing the PFM reports for all PFMs in this experiment. By pressing "Report Preferences" you can select what options are generated in the report.

Advanced
The fields in the advanced tab page define behavior at various points in the replications.

Start of experiment: This pick list is called when the experiment begins running. It is used to set up certain variable values before any scenarios begin to run. This function is only called once, before the first scenario runs. See the start of experiment pick list. Start of scenario: This pick list is called before the first replication in a scenario. It is called once for each scenario. See the start of scenario pick list. End of warmup period: Thispick list is called when the warm-up time of the replication has expired. See the end of warm-up pick list. End of replication: This pick list is called when the end time of a replication has expired. It is run once for each replication. See the end of replication pick list. End of experiment: This pick list is called when the experiment is over. It is used to write model data at the end of the run. This function is only called once, after the last scenario runs. See the end of experiment pick list.

Shift Schedules
Shift Schedules are accessed in the Tools menu. They are used to schedule state changes, such as scheduled down-time, for specific objects in the model. Each shift schedule may control many objects, and each object may be controlled by many shift schedules. A model may contain any number of shift schedules.

Name - The name of the shift schedule. This should be descriptive of the function this shift schedule plays in the model. For example: Weekend or Shift Change. Adding and Removing TimeTable Members - At the top of the window, the panel on the left shows objects in the model. The panel on the right shows the list of the TimeTable's members. Select objects in the left panel and click on the button to add the objects to the member list. Select objects from the member list on the right

and click the

button to remove those members from the list.

Edit Work Schedule - This button will open a table where you can edit the schedule, either as a weekly schedule or a daily schedule. Down Function - This pick list is executed when the objects in the member list go down. It is executed once for each object in the member list. This is where you specify what to do in order to put the object into it's Down condition. The default pick list option tells the members to first reassign the resource's active task (if there is one) to another resource, then have the resource travel to a "home" location to wait off its down time. The travel time of the resource will count towards the total down time specified in the Work Schedule. Resume Function - The pick list is executed when the objects in the member list resume their operation. It is executed once for each object in the member list. This is where you specify what to do in order to resume the object. The default option puts the resource into a state ready to receive requests. OnDown - This pick list is fired immediately after the Down Function, but it is only executed once, instead of once for each object in the member list. See Down/Resume Trigger. OnResume - This pick list is fired immediately after the Resume Function, but it is only executed once, instead of once for each object in the member list. See Down/Resume Trigger. Note: on using several down schedules for the same object: If one object has several down schedules, each with its own down state, you may come across problems with the state diagrams of your objects. This is caused because of the nature of the stopobject() and resumeobject() commands. If two entities request the same object to stop, the object does not remember the state for each stop request. For more information, refer to the stopobject() command in the command summary.

User Commands
The user commands tool lets you add, delete, and edit custom commands in your model.

To add a command, click the "Add" button at the bottom. This will create a new command. To delete a command, select it from the list on the left and click the "Remove" button. To edit a command, select it from the list on the left, then enter the name of the command, the parameter list, the return type, a description, and an example. Then in the Code picklist option, enter the code implementation for the command. To access the parameters passed into the command, use the commands parval() and parnode(). For example, if the first parameter is supposed to be a reference to an object, execute parnode(1) to get a reference to that parameter. If it is a number value, call parval(1) to get the value. Once you have created and edited your command, you can call that command like any other FlexSim command. It will appear in blue when typing code and will appear in the command summary. Note on Parameters and Return Type: The values specified here will be used by the Flexscript parser. The number of parameters and their datatypes will give Flexscript warnings if not passed as documented in the Parameters section here. If the return type is incorrecly used in code, it will return a Flexscript error and not build correctly. You can specify the parameters list as (...) and leave the return type blank for the Flexscript parser to ignore them. For examples of parameter lists and return types, view the Command Documentation. When you open the command documentation from the menu Help > Commands, the user commands will be shown in the command documentation in addition to all of the built-in Flexscript commands. The description field shown above will be displayed as html so you can use html markup for formatting, such as <b> and <\b> for bold. Because the description allows for html markup, some standard characters do not work properly, such as <, >, &, and new line characters. To display these types of characters, you can use special markup codes, such as "&gt;" (without the quotes) for a > symbol and <br/> for a line break. If any of the commands' descriptions container invalid html markup, FlexSim may throw an exception when you try to open the Users Manual and your commands will not be properly documented. Note on calling user commands: When calling a user command in C++, all parameters passed will need to be converted to a number, or else you may get compiler errors. To convert a parameter to a number, use the tonum() command. Note on calling user commands from C++: When calling a user command from C++, all parameters passed will need to be converted to a number, or else you may get compiler errors. To convert a parameter to a number, use the tonum() command.

User Events
User Events are accessed in the Tools menu. They are Flexscript functions that execute at set times during the models run, but are not connected with any specific, visible object. They are created in a special node in the model called Tools, in a sub-node called UserEvents. A model can have any number of user events.

Name - This is the name of the user event. It should be descriptive of what the user event does. Execute event on reset only - If this box is checked the event will only be executed when the reset button is pressed. First Event Time - This is the time that the user event will occur. Repeat Event - If this box is checked, as soon as the user event finishes, it begins counting towards the execution time again. User events will always repeat in regular intervals defined by the execution time. Event Code - This is where the Flexscript code for the event is written. Any valid Flexscript statements can be used in this field.

FlexSim Coding
1. Writing Logic in FlexSim 2. Basic Modeling Functions

Basic Modeling Functions and Logic Statements


Here we have provided a quick reference for commands that are used most often in FlexSim. For more detailed information on these commands, refer to the command summary.

Object Referencing
The following commands and access variables are used in referencing objects in FlexSim.

current and item


current - the current variable is a reference to the current resource object. It is often an access variable in pick lists. item - the item variable is a reference to the involved item for a trigger or function. It is often an access variable in pick lists.

Referencing Commands command(parameter list)


first(node) last(node) rank(node,ranknum) inobject(object,portnum) outobject(object,portnum) centerobject(object,portnum) next(node)

Explanation
This returns a reference to the first ranked object inside of the object passed This returns a reference to last ranked object inside of the object passed This returns a reference to the object at a given rank inside the object passed This returns a reference to the object connected to the input port number of the object passed This returns a reference to the object connected to the output port number of the object passed This returns a reference to the object connected to the center port number of the object passed This returns a reference to the next ranked object of the object passed

Example
first(current) last(current) rank(current,3) inobject(current,1) outobject(current,1) centerobject(current,1) next(item)

Object Attributes command(parameter list)


getname(object) setname(object,name) getitemtype(object) setitemtype(object,num) setcolor(object,red) setcolor(object,green) setcolor(object,blue) setcolor(object,white) ... colorred(object) green, blue, white... setobjectshapeindex(object,indexnum)

Explanation
This returns the name of the object This sets the name of the object This returns the itemtype value of the object This sets the itemtype value of the object

This sets the color of the object

This sets the color of the object to red, blue, green, white, etc. This sets the 3D shape of the object

setobjecttextureindex(object,indexnum) This sets the 3D texture of the object setobjectimageindex (object,indexnum) This sets the 2D texture of the object. This usually only applies if you are using the planar view.

Object Spatial Attributes command(parameter list)


xloc(object) yloc(object) zloc(object) setloc(object,xnum,ynum,znum)

Explanation
These commands return the x,y, and z locations of the object This sets the x, y, and z location of the object

xsize(object) ysize(object) zsize(object) setsize(object,xnum,ynum,znum)

These commands return the x,y, and z size of the object This sets the x, y, and z size of the object

xrot(object) yrot(object) zrot(object) setrot(object,xdeg,ydeg,zdeg)

These commands return the x,y, and z rotation of the object This sets the x, y, and z rotation of the object

Object Statistics command(parameter list)


content(object) getinput(object) getoutput(object) setstate(object,statenum) getstatenum(object) getstatestr(object) getrank(object) setrank(object,ranknum) getentrytime(object) getcreationtime(object)

Explanation
This returns the current content of the object This returns the input statistic of the object This returns the output statistic of the object This sets the current state of the object. This returns the current state value of the object This returns the current state of the object as a string This returns the rank of the object This sets the rank of the object This returns the time the object entered the object it is currently in This returns the time the object was created

Object Labels

command(parameter list)

Explanation

getlabelnum(object,labelname) This returns the value of the object's label getlabelnum(object,labelrank) setlabelnum(object,labelname ,value) setlabelnum(object,labelrank ,value) getlabelstr(object,labelname) setlabelstr(object,labelname ,value) setlabelstr(object,labelrank ,value) label(object,labelname) label(object,labelrank)

This sets the value of the object's label

This gets the string value of the object's label

This sets the string value of the object's label

This returns a reference to the label as a node. This command is often used if you have a label that is used as a table.

Tables command(parameter list)


gettablenum(tablename,rownum,colnum) gettablenum(tablenode,rownum,colnum) gettablenum(tablerank,rownum,colnum) settablenum(tablename,rownum,colnum,value) settablenum(tablenode,rownum,colnum,value) settablenum(tablerank,rownum,colnum,value) gettablestr(tablename,rownum,colnum) gettablestr(tablenode,rownum,colnum) gettablestr(tablerank,rownum,colnum) settablestr(tablename,rownum,colnum,value) settablestr(tablenode,rownum,colnum,value) settablestr(tablerank,rownum,colnum,value) settablesize(tablename,rows,columns) settablesize(tablenode,rows,columns) settablesize(tablerank,rows,columns) gettablerows(tablename) gettablerows(tablenode) gettablerows(tablerank) gettablecols(tablename) gettablecols(tablenode) gettablecols(tablerank) clearglobaltable(tablename) clearglobaltable(tablenode) clearglobaltable(tablerank)

Explanation
This returns the value in the specified row and column of the table

This sets the value in the specified row and column of the table

This returns the string value in the specified row and column of the table

This sets the string value in the specified row and column of the table

This sets the size of the table in rows and columns

This returns the number of rows in the table

This returns the number of columns in the table

Sets all number values in the table to 0

Object Control

command(parameter list)
closeinput(object) openinput(object) closeoutput(object) openoutput(object) sendmessage(toobject,fromobject, parameter1,parameter2,parameter3)

Explanation
This closes the input of the object This re-opens the input of the object This closes the output of the object This re-opens the output of the object This causes the message trigger of the object to fire

senddelayedmessage(toobject,delaytime,fromobject, This causes the message trigger of the object to fire after a certain delay parameter1,parameter2,parameter3) time stopobject(object,downstate) resumeobject(object) stopoutput(object) resumeoutput(object) stopinput(object) resumeinput(object) insertcopy(originalobject,containerobject) moveobject(object,containerobject) This tells the object to stop whatever its operation is and go into the given state This allows the object to resume whatever its operation is This closes the output of the object, and accumulates stopoutput requests This opens the output of the object once all stopoutput requests have been resumed This closes the input of the object, and accumulates stopinput requests This opens the input of the object once all stopinput requests have been resumed This inserts a new copy of the object into the container This moves the object out of its current container into its new container

Advanced Functions
Object Variables command(parameter list)
getvarnum(object,variablename) setvarnum(object,variablename, value) getvarstr(object,variablename) setvarstr(object,variablename, string) getvarnode(object,variablename)

Explanation
This returns the number value of the variable with the given name This sets the number value of the variable with the given name This returns the string value of the variable with the given name This sets the string value of the variable with the given name This returns a reference to the variable with the given name as a node

TaskExecuter Control
For more information on controlling TaskExecuters, refer to the task sequence section.

Prompts and Printouts

command(parameter list)
pt(text string) pf(float value) pd(discrete value) pr() msg(title,caption) userinput(targetnode,prompt) concat(string1,string2,etc.)

Explanation
Prints text to the output console Prints a floating point value to the output console Prints an integer value to the output console Creates a new line in the output console Opens a simple Yes, No, Cancel dialog Opens a dialog box where you can set the value of a node in the model This returns the string concatenation of two or more strings

More Advanced Functions


Here are more advanced functions that you might use. We do not provide their parameter lists here. For more information, refer to the command summary. Node commands - node(), nodeadddata(), getdatatype(), nodetopath(), nodeinsertinto(), nodeinsertafter(), getnodename(), setnodename(), getnodenum(), getnodestr(), setnodenum(), setnodestr(), inc() Data changing commands - stringtonum(), numtostring(), tonum(), tonode(), apchar() Node table commands - setsize(), cellrc(), nrows(), ncols() Node table commands - setsize(), cellrc(), nrows(), ncols() Model run commands - cmdcompile(), resetmodel(), go(), stop() 3D custom draw code commands - drawtomodelscale(), drawtoobjectscale(), drawsphere(), drawcube(), drawcylinder(), drawcolumn(), drawdisk(), drawobject(), drawtext(), drawrectangle(), drawline(), spacerotate(), spacetranslate(), spacescale() Excel commands - excellaunch(), excelopen(), excelsetsheet(), excelreadnum(), excelreadstr(), excelwritenum(), excelwritestr(), excelimportnode(), excelimporttable(), excelclose(), excelquit() ODBC commands - dbopen(), dbclose(), dbsqlquery(), dbchangetable(), dbgetmetrics(), dbgetfieldname(), dbgetnumrows(), dbgetnumcols(), dbgettablecell(), dbsettablecell() Kinematics - initkinematics(), addkinematic(), getkinematics(), updatekinematics(), printkinematics()

Writing Logic in FlexSim Healthcare


FlexSim Healthcare provides an option for writing custom logic: Flexscript. Flexscript works immediately in the model without having to be compiled. Flexscript is nearly identical to C++ in its syntax and application, but is simplified for ease of use. This topic covers the programming options available in Flexscript.

Where to get help


Whenever you need help with what commands to use and how to use them, you can refer to the "Commands" documentation found through FlexSim Healthcare's Help menu.

General Rules
Here are some general rules you will need to know when creating your own logic. language is case sensitive (A is not the same as a) no specific format is required (free use of spaces, tabs and line returns is encouraged) numbers are double precision floating point values unless otherwise specified. text strings are usually entered between quotes. mytext" parenthesis follow a function call and commas separate the arguments of the function. moveobject(object1,object2); > a function or command will always end with a semi-colon > parenthesis can also be used freely to make associations in your math and logic statements. > curly braces are used to define a block of statements. > to comment out the rest of a line use // > do not use spaces or special characters in name definitions (_ is ok). > named variables and explicit values can be interchanged in writing expressions. >

Math Operations
The following list show different math operations that can be performed on values.

Operation
+ * / % (integer mod) sqrt() pow() round() frac() fabs()

Floating Point Example (=solution)


1.6+4.2 (=5.8) 5.8-4.2 (=1.6) 1.2 * 2.4 (=2.88) 6.0/4.0 (=1.5)

Integer Example (=solution)


2+3 (=5) 5-2 (=3) 3*4 (=12) 20/7 (=2) 34%7(=6)

sqrt(5.3) (=2.3) pow(3.0,2.2) (=11.2) round(5.6) (=6) frac(5.236) (=0.236) fabs(-2.3) (=2.3) pow(3,2) (=9)

fmod() (floating point mod) fmod(5.3,2) (=1.3) Be aware as you write your logic that, by default, all values in FlexSim Healthcare are double precision floating point, so you will usually be using the operations as they apply to floating point numbers. Note: By performing operations on floating point numbers, some precision may be lost. Note: Be careful in using these operations while mixing integer types with floating point types, or with using just integer types. For example, the / operator will return an integer if both operators are integers. This may not be what you want to get out of the operation, in which case you will need to use floating point types instead of integer types.

Comparing Variables
The following table shows different operations for comparing two values or variables.

Operation
> (greater than) < (less than) >= (greater than or equal to) <= (less than or equal to) == (equal to) != (not equal to) comparetext() 1.7>1.7 (false) -1.7 < 1.5 (true) 45 >= 45 (true) 45 <= 32 (false) 45 == 45 (true) 45 != 35 (true)

Example (solution)

comparetext(getname(current),"Processor5")

Warning: The == operator can often cause problems if you are comparing two double precision floating point values, and one or both of those values have been calculated using math operations. When doing math operations, floating point values may lose some precision. Since the == operator will only return true if all 64 bits of each value are exactly the same, even a small precision loss will cause the == operator to return false. In such cases, you will want to instead verify that the two values are within a range of each other. For example: fabs(value1 - value2) < 0.000001, will return true if the two values are practically equal for all intents and purposes.

Relating Variables
The following table shows different operations for relating several comparisons. The following table shows different operations for relating several comparisons.

Operation
&& (logical AND) || (logical OR) ! (logical NOT) min() max()

Example
x>5 && y<10 x==32 || y>45 !(x==32 || y>45) min(x, y) max(x, y)

Setting and Changing Variables


The following tables show ways of setting and changing variables.

Operation
= += -= *= /= ++ -x = x + 2;

Example

x += 2; (same as x = x + 2) x -= 2; (same as x = x - 2) x *= 2; (same as x = x * 2) x /= 2; (same as x = x / 2) x ++; (same as x = x + 1) x --; (same as x = x - 1)

Variable Types
FlexSim Healthcare uses just four variable types. Each of the four types can also be used in an array structure. The following explains each of these types.

Single Variables

Type
int double string treenode integer type

Description

double precision floating point type text string reference to a FlexSim node or object

Array Variables Type


intarray doublearray stringarray treenodearray

Description
an array of integer types an array of double types an array of string types an array of treenode types

For more information on how the treenode (or FlexSim Healthcare node) type works, refer to the FlexSim Healthcare tree structure

Declaring and Setting Variables


The following are some examples of how to declare and set variables. int index = 1; double weight = 175.8; string category = "groceries"; treenode nextobj = next(current);

Declaring and Setting Array Variables


The following are examples of how to use array types. intarray indexes = makearray(5); // makes an array with 5 elements indexes[1] = 2; // in FlexSim Healthcare, arrays are 1-based indexes[2] = 3; indexes[3] = 2; indexes[4] = 6; indexes[5] = 10; doublearray weights = makearray(3); fillarray(weights, 3.5, 6.7, 1.4); // fillarray is a quick way of setting the array values stringarray fruits = makearray(2); fruits[1] = "Orange"; fruits[2] = "Watermelon"; treenodearray operators = makearray(4); operators[1] = centerobject(current, 1); operators[2] = centerobject(current, 2); operators[3] = centerobject(current, 3); operators[4] = centerobject(current, 4);

Executing Commands
Executing a command in FlexSim Healthcare is made of following parts. First type command's name, followed by an open parenthesis. Then enter each parameter of the command, separating multiple parameters by commas. Each parameter can be a variable, an expression of variables, or even a command itself. Finish the command with a close parenthesis, and a semi-colon. For detailed information on the commands, their functionality and parameter lists, refer to the "Commands" documentation found through FlexSim Healthcare's Help menu. For a quick reference of the most used commands in FlexSim Healthcare, refer to the section on basic modeling functions.

Syntax

Examples
coloryellow(current); setrank(item, 3 + 7); setitemtype(item, getlabelnum(current, "curitemtype"));

commandname(parameter1,parameter2,parameter3...);

Flow Constructs
The following are constructs which allow you to modify the flow of your code.

Logical If Statement
The if statement allows you to execute one piece of code if an expression is true, and another piece of code if it is false. The else portion of the construct is optional.

Construct
if (test expression) { code block } else { code block }

Examples
if (content(item) == 2) { colorred(item); } else { colorblack(item); }

Logical While Loop


The while loop will continue to loop through its code block until the test expression becomes false.

Construct
while (test expression) { code block }

Examples
while (content(current) == 2) { destroyobject(last(current)); }

Logical For Loop


The for loop is like the while loop, except that it is used usually when you know exactly how many times to loop through the code block. The start expression is executed only once, to initialize the loop. The test expression is executed at the beginning of each loop and the loop will stop as soon as this expression is false, just like the while loop. The count expression is executed at the end of each loop, and typically increments some variable, signifying the end of one iteration.

Construct
for(start expression;test expression;count expression) { code block }

Examples
for (int index = 1;index <= content(current);index++) { colorblue(rank(current,index)); }

Logical Switch Statement


The switch statement allows you to choose one piece of code to execute out of several possibilities, depending on a variable to switch on. The switch variable must be an integer type. The example below sets the color of items of type 1 to yellow, type 5 to red, and all other types to green.

Construct

Examples
int type = getitemtype(item); switch (type) { case 1: { coloryellow(item); break; } case 5: { colorred(item); break; } default: { colorgreen(item); break; } }

switch (switchvariable) { case casenum: { code block; break; } default: { code block; break; } }

Redirection
Each of the flow constructs described can be redirected mid-execution with either a continue, break or return statement. The following explains how each of these statements work.

Construct
continue;

Examples
Only valid in For and While loops. Halts the current iteration of the loop and goes on to the next iteration in the loop. In a For loop the counter is incremented before continuing. Only valid in For, While and Switch statements. Breaks out of the current For, While or Switch block and continues with the line immediately following this block. Nested statements only break out of the current statement and continue on in the containing statement. Returns out of the current method entirely and continues with the line following the code that called this method. A return value may be required if the method returns a value.

break;

return;

Miscellaneous Concepts
1. 2. 3. 4. 5. 6. FlexSim Tree Structure State List Kinematics FlexSim XML Advanced Undo Ports

Advanced Undo Customization


This topic describes advanced mechanisms for storing undo history. This is meant mostly for developers of custom user interfaces and libraries.

When Advanced Undo is Needed


In FlexSim, for the most part, undo/redo just works. You don't need to worry much about what is being recorded to the undo history, because it's all automatic. However, there are some instances where you might need to customize the undo history recording to suit your needs. Some examples of when you might want to customize undo history recording are: When you have created a customized object, and that object changes certain variable values as the object is dragged around in the model, i.e. in its OnPreDraw or OnDrag functionality. You may want those values to go back to their original state before the object was dragged. If you have custom functionality in a user library's drop script that you do NOT want recorded in the undo history. By default, whenever the user does a drag/drop operation from the library icon grid, FlexSim will automatically start an "aggregated undo" operation, which essentially retools several low-level commands to record changes that are made. We'll talk about this in more detail later, but for some dropscripts, you may need to temporarily "turn off" undo recording, then execute your functionality, then turn it back on. For example if you are performing functionality that opens a window. If you create a tool window that is used to modify the model, like the Edit Selected Objects or Edit Highlighted Object tool windows, then you'll need to add code to the buttons of those windows that explicitly does undo recording. In FlexSim, all things that are done in a 3D view, a tree view, or a table view, as well as all operations done in tool windows that focus around those views, are undo-able, so if you design a tool window that is used with one of these views, you'll need to make it undo-capable.

Creating an Undo Record Explicitly


To create an undo record before executing a piece of code, call beginaggregatedundo(). Pass in the view that this undo is associated with. If you pass in NULL as the view, then it will be associated with FlexSim's global undo history. And pass in a description of the operation being done. The beginaggregatedundo() command will return back a unique id for the undo record that you've created. Then execute the code that you want to be undo-able, then call endaggregatedundo(), passing in the view and the undo id. When you call beginaggregatedundo(), FlexSim will retool several low-level

commands, so that subsequent calls that you make to those commands, or calls to those commands by other commands that you call, will record changes to the undo history. The commands that are retooled are as follows: nodeadddata() setnodenum()/set() setnodestr()/sets() nodedeldata() nodeinsertinto() nodeinsertafter() nodejoin() nodepoint() nodebreak() setname() clearcontents() createcopy() createinstance() switch_cppfunc(),switch_flexscript()... (all switch_... commands) transfernode() transfernodeobj() moveobject() setrank() destroyobject() destroynode()

Ignoring Undo
If you are inside of an aggregated undo and you want FlexSim to ignore a set of commands, call beginignoreundo(), execute the commands, then call endignoreundo(). This is especially useful in dropscripts of a user library. FlexSim automatically creates an aggregated undo record that applies to all functionality executed as part a drag/drop operation from the library icon grid, so all code that executes in a drop script is being recorded as part of an undo record. To bypass this for certain functionality, surround it with beginignoreundo() and endignoreundo()

Undo Tracking on a Custom Object's Drag


You may also want FlexSim to track changes to a custom object's variable value, or the location, rotation and scale of an object that the custom object changes as it is dragged. One example of this being used is in the Crane object in FlexSim's standard library. When you drag on one of the Crane's sizers, there are actually several objects behind the scenes that the Crane resizes as you drag. Also, the Crane has three variable values defining the x,y, and z location of the Crane's frame that change as you drag the Crane to a different position in the model. In order for undo functionality to work on the Crane, it must tell FlexSim to track undo information on those objects

that it is changing as the user drags. To add undo tracking to an object or number variable, call applicationcommand("addundotracking", tonum(view), tonum(obj_or_variable)). The Crane performs this as part of its OnClick event, when the user clicks on the Crane.

Introduction to FlexSim Tree Structure


FlexSim is completely designed around the concept of a tree structure. All information in FlexSim is contained within the FlexSim tree, including the library objects, commands, and all model information. This tree hierarchy is made of individual nodes that link together and hold information.

Nodes
A node is the building block of a FlexSim tree. All nodes have a text containing the name of the node. Nodes can simply be a container for other nodes, can be a keyword used to define an attribute of an object, or may have a data item. The data item types which may be attached to a node are: number, string, object, or pointer. To attach data to a node, right-click on the node and go to the Insert menu option. You will see the four options to add data to a node. There are also shortcut keys for adding number, string(text), object, or pointer data. These are the keys N, T, O, and P. To add data to a node using a shortcut key, click on the node, then press the appropriate key. Nodes can also hold executable code. To make a node executable, first add string data to the node, and then toggle the node as either a C++ or a Flexscript node. To toggle a node as one of these types, right-click on the node and go to the Build menu. The symbols for the different types of nodes are shown here: Standard: Object: Attribute/Variable: Function (C++): Function (FlexScript): Nodes can be added and deleted from the tree. To delete a node, simply click the node and then hit the delete key. To insert a node, right-click on an existing node and choose Edit | Insert. This will add a new node immediately after the node that was clicked on. The shortcut for this operation is to hit the spacebar after first highlighting a node. Nodes can also contain a sub list of nodes called the content branch. If a node contains sub nodes it can be expanded by pressing the button. To insert a node into the content of an existing node, choose the option Edit | Insert Into, or hit the Enter key as a shortcut. A node that has object data may contain a second sub list of nodes that are contained

in a separate branch of the tree. This sub list of nodes is called the object attribute tree, and contains data that describes the properties of the object. A node containing object data may typically be referred to as an object node. When you click on an object node you will see a greater than symbol to the left of the node. Clicking on this button will open the object attribute tree branch. The following picture shows an expanded object attribute tree for the Queue object in the library tree.

For nodes with object data, the attribute tree can contain many special attribute nodes. If a node is inside an object and has the name of a key attribute, it will have a special meaning to the object. The actual meaning of the attribute depends on what the attribute is and the object type. As an example, there are attributes for an object's position: 'spatialx', 'spatialy', 'spatialz'. In addition to containing all model, library, and project information, the FlexSim tree also stores all windowing and interface information. All open windows, menus, toolbars and buttons have a corresponding representation in the FlexSim tree. We call these types of nodes view objects.

General Organization Trees


FlexSim's root tree structure is split up into two parts. These are the Project Tree and the View Layout Tree. The project tree contains the Executive data, the Library, and the Model. The view layout tree contains information on windows, editors, and other user interfaces. It also manages active windows.

Project Tree:
To view the project tree, click on the main menu option: View | System Info | MAIN tree. The project tree holds projects at its most basic level. Each project holds the following crucial sub trees: exec, library, model, undo, media.

Exec
This tree contains simulation executive data. This includes the simulation time, the eventlist, as well as other information with running a model.

Library
The library of objects used by the model.

Model
The simulation model.

Undo
Holds undo history. A numerical value for this node is the limit on the number of undo steps. If there is no numerical data, undo will be disabled. Undo functionality may also be globally disabled.

Media
Stores Images, 3D models and Sounds.

View Layout Tree:


To view the project tree, click on the main menu option: View | System Info | VIEW tree. The view tree contains data for creating, storing, and using graphical user interfaces for objects.

FlexSim XML
With the release of version 5, FlexSim includes improved functionality for saving model, library and tree files in XML format. There are many advantages to using this new capability in your model development, including: Since XML is an ascii/text based format, it increases the utility of using content management and versioning software such as Subversion, CVS, Microsoft Visual SourceSafe, git, etc. to manage the development of a model. These systems automatically track a history of changes to a model or project, and for ascii/text based files, they allow you to see line-by-line change logs for the files, as well as revert line-item changes if needed. With the added benefit of versioning systems comes the ability to develop a model concurrently by different modelers using a much more stream-lined method. No more saving off individual t files from one modeler's changes to a model and loading them manually into the master model. When saving to XML format, if one modeler is working on one portion of the model, only that portion of the model file changes when saved, so when the modeler checks his changes into the versioning system's repository, another modeler can automatically merge those changes into his copy. If there are conflicts, where two modelers change the same part of the model, then the versioning system has tools that allow modelers to easily see in the XML file where the conflicts occur and quickly perform the manual conflict resolution. FlexSim also has the added ability to distribute a single model across multiple XML files. This increases your control over how to manage the model development in your versioning system, and makes conflict resolution even easier. The distributed save mechanism also opens the door for much more automated control of FlexSim. By saving small pieces of your model off into separate XML files, you can auto-regenerate one or more of those XML files outside of FlexSim, consequently changing the configuration of the model for the purpose of running different scenarios.

Tutorial
This tutorial will take you through saving a model as XML, and how you can configure the distributed save.

Build a Simple Model


First build a simple example model containing a Source, Queue, Processor and Sink.

Save in XML Format


Save the model, and in the save dialog, choose "FlexSim XML" from the drop-down at the bottom. Save the model as "PostOfficeXML.fsx".

Now you've saved the file in FlexSim's XML format. You can view the file in a regular text editor like Notepad, Visual Studio, Notepad++, EditPlus, etc.

Unless you plan on doing automated changes to the XML file, it's not necessary to know all the details of the file format. In simple terms, the primary tag in FlexSim XML is the <node> tag, representing a node in FlexSim. The node's name is described in the <name> tag, and the node's data, if applicable, is described in the <data> tag. If you do plan on doing automated changes, and need a more detailed definition of the xml format, you can refer to FlexSim's xml schema.

Version Management Utilities


To give you a better idea of the advantages of using an XML format, we'll go through some of the things that you might do with a versioning system. At FlexSim we use Subversion, with TortoiseSVN as our client-side tool, and have found this to meet all of our development needs quite sufficiently. Details of installing and configuring a version management system are outside the scope of this tutorial. You can find many install and setup helps online. As part of this tutorial we will simply assume that, once the model has been saved, a Subversion repository is set up for the model. When the Subversion repository is initially created, the file will appear with a green icon indicating that your copy is "clean", or you haven't made any changes since your last check-in.

Now let's say we make a small change to the model, such as moving the Queue to a different location and then saving the model again.

Once saved, you'll notice that the file's icon has changed to a red symbol, meaning the file is "dirty", or it has changed since the last check-in. You can also right-click the file, and see exactly what's changed by choosing the "Diff" operation. This will give you a difference comparison of your current copy of the file with the last version that you checked-in.

TortoiseSVN provides a simple diff utility, but you can also configure it to use a third-party comparison tool such as WinMerge.

Using the diff tool you can see where the model has been changed, namely in spatialx and spatialy attributes. You can revert line-item changes in the diff tool if you don't want those changes applied.

Distributed Save
Next let's distribute the model across multiple files. To do this you create a "FlexSim File Map" file. This is an xml file with the .ffm extension. It must be placed in the same directory as the model's .fsx file, and, except for the extension, must be given the same name as the .fsx file. So, let's create that file. Let's also create a subdirectory to put the distributed files into.

Now edit PostOfficeXML.ffm in a text editor. The first thing we'll do is put the node model/Tools/active into a different file. This is something you'll probably want to do always if you're using version management. The node model/Tools/active stores all of the windows open in the model, so if you're editing a model and change or reposition the windows that are open, that will change the model file. For version management this is often just static that doesn't need to be tracked, so we'll have the node saved off to a different file, and then we can just never (or at least rarely) check that file into the version management system. Specify the following code: <?xml version="1.0" encoding="UTF-8"?> <FlexSim-file-map version="1"> <map-node path="/Tools/active" file="distributedfiles\windows.fsx" file-map-method="single-node"/> </FlexSim-file-map> Save the file map, then go back into FlexSim. Save the post office model again under the same name "PostOfficeXML.fsx". Now look in the distributedfiles directory. You'll see that it contains a new xml file named windows.fsx. This xml holds the definition of the node model/Tools/active. All interaction with the model remains the same, i.e. from FlexSim you just load and save the main xml model file, but now the model is distributed across multiple files. In the file map, the main document element is the <FlexSim-file-map> tag. Inside the main document element should be any number of <mapnode> elements. Each <map-node> element should have a path attribute, a file attribute, and a file-map-method attribute. The path attribute should specify the path, from the main saved node, to the node that is going to be saved into the distributed file. The file attribute specifies the path, relative to the saved model file, to the distributed file that you want to save. The file-map-method should either have a value of "singlenode" or "split-points". In this case "single-node" means you want to save all of the active node into windows.fsx. Now let's do an example of the "split-points" method. Let's say we want to save the Tools folder in one file, the Source and Queue into another file, and the Processor and Sink in a third file. To do this, add another <map-node> element to the file map: <?xml version="1.0" encoding="UTF-8"?> <FlexSim-file-map version="1"> <map-node path="/Tools/active" file="distributedfiles\windows.fsx" file-map-method="single-node"/> <map-node path="" file="distributedfiles\Tools.fsx" file-map-method="split-points"> <split-point name="Source1" file="distributedfiles\Source_Queue.fsx"/> <split-point name="Processor3" file="distributedfiles\Processor_Sink.fsx"/> </map-node>

</FlexSim-file-map> Now save the file, save your FlexSim model, and again you'll see new files created in the distributedfiles directory. If a <map-node> element uses the "split-points" method, then it can have <split-point> sub-elements. Each split-point should have a name, defining the name of a node inside the map-node's defined node, and a file attribute defining the file to save to. The map-node has a path="" attribute. This means that it applies to the root node, or the model itself. The map-node's file attribute defines the first file to use. This configuration tells FlexSim to save all sub-nodes in the model up to but not including the node named "Source1" to the file "distributedfiles\Tools.fsx", save everything from Source1 up to but not including the node named "Processor3" in "distributedfiles\Source_Queue.fsx", and save everything from Processor3 to the end in "distributedfiles\Processor_Sink.fsx".

Why Distribute?
The main reason you would want to distribute your model across multiple files is for version management. It allows you to easily see what you've changed in your model by seeing what files, and consequently which parts of the tree, have changed. If you inadvertently changed one piece of the model, you can easily see that and then revert that change if needed. When multiple modelers are developing the model, one modeler can essentially confine himself to one part of the model tree, and by associating that part of the tree with a specific file, it makes it much easier to merge changes from different developers, it reduces the chance of conflicts in the merge, and makes it easier to do a manual merge if needed. Note on connections: FlexSim's XML save mechanism does have one catch regarding input/output/center port connections, as well as any other mechanism that uses FlexSim's coupling data. If you change connections in one portion of your model, it will actually change the serialized values of all connections/coupling data that occur after those connections in the tree, even if those connections were not changed. This can very easily cause merge issues if multiple modelers are changing connection data. However, if you distribute the model across multiple files, connection changes where both connection end-points are within the same file will only affect that file, and will not change other files. So if you can localize large "connection sets" into individual files, you can minimize the effect of changes and subsequently minimize merge conflicts.

Kinematics
Purpose
Kinematic functionality allows you to have a single object perform several travel operations simultaneously, each travel operation having its own acceleration, deceleration, startspeed, endspeed, and maximum speed properties. For example, an overhead crane usually has several motors that drive it. One motor drives the bridge along a railing, while another motor drives a trolley along the bridge, while another lifts the hook or grabber by a cable. Each of these motors may have their own acceleration, deceleration, and maximum speed properties. Having these different motors work simultaneously gives the motion of the crane a very dynamic behavior and look. Before kinematics were introduced, the simplest way to simulate this behavior was to have three different objects hierarchically ordered in the model tree, each object simulating one motion or kinematic. This, however, could often become tedious and unfriendly. Kinematic functionality attempts to fix this problem by allowing one object to do several motions or kinematics simultaneously. This help page defines the API for kinematic functionality. In the future, more functionality will be built on top of this API, such as a tablekinematics command that will automatically build kinematics for you by looking up values from a table, and a TASKTYPE_KINEMATICS task. But for now, this is the core API for kinematics.

General Use
1. Call the initkinematics command. This initializes data for the kinematics, saving things like the start location and rotation of the object you want to apply motion to. 2. Call the addkinematic command. This gives travel/rotate operations to the object. For example, you can tell the object, starting in 5 seconds, to travel 10 units in the x direction, with a given acceleration, deceleration, and max speed. Then you can tell the object, starting in 7 seconds, to travel 10 units in the y direction, with a different acceleration, deceleration, and max speed. The effect of these two operations is that the object will start traveling in the x, then will start simultaneously accelerating in the y, following a parabolic curved path to the destination. Each call to addkinematic will add another operation to the object. 3. Call the updatekinematics command. This command should be called when the object is being redrawn. This calculates the current position and rotation of the object.

The initkinematics Command


The Blank Node For the initkinematics command, as well as all other kinematics commands, you must

pass a reference to a blank node as the first parameter. This specifies where you want kinematic information to be stored, or, if you are getting information out of it, where kinematic information has been stored. The node needs to be an otherwise unused node, so that kinematic functionality can store data as needed. For modelers, this node will most likely be a label. Once kinematics have been initialized, the node will display the text "do not touch". This node should not be clicked on in a tree or table view while a kinematic operation is in process, or the kinematic data may be corrupted. Overloading The initkinematics command is overloaded, so you can call initkinematics with two different parameter sets, depending on your situation. Parameters for these two overloads are as follows.

void initkinematics(treenode datanode, treenode object [, int managerotation, int localcoords] )


datanode - This is the blank node for kinematic data. object - This is the object that will do the moving. managerotation - This optional parameter is either 1 or 0. If 1, the object will always point in the direction of travel. Default: 0 localcoords - This optional parameter is either 1 or 0. If 1, then the object will travel according to its container coordinate system. If 0, then it will travel according to its own coordinate system. Default: 0 This parameter set assumes you have an object that you want to move, like a transporter. The first parameter, again, is a blank node kinematic data, either a label, attribute, or variable. The second parameter is the object that will do the moving. The command will save off the object's initial location and rotation. The optional parameter managerotation is either 1 or 0. If 1, the rotation of the object will be set according to the velocity of the object at any given time. By default, the object's positive x direction will always point in the direction of the object's current velocity. This would be used, for example, if you have a truck that you always want to point forward as it travels. If managerotation is passed as 0, then the object won't rotate unless given commands to rotate, which will be explained later. If you do not specify this parameter, then by default, managerotate is set to 0. The optional localcoords parameter specifies the orientation of subsequent travel command locations. For example, if my truck is rotated 45 degrees, and I want it to travel 5 units in the x direction, this can be interpreted in two different ways. Do I want it to travel 5 units in x according to the truck's coordinate system, or 5 units in x according to the model's coordinate system (or the coordinate system of the truck's container)? In the former

case, the object would actually travel 3.5 units in the x direction and 3.5 units in the y direction according to the model's coordinate space. In the latter case, however, the object would travel the usual 5 in the x direction according to the model's coordinate space. The localcoords parameter specifies which coordinate system you want to use. If 1 is passed, the object's coordinate system will be used (the former case). Note that only the object's initial coordinate system will be used to calculate locations, not subsequent coordinate systems if the object rotates later on in the kinematics. If 0 is passed, the object's container's coordinate system will be used (the latter case). If you do not specify this parameter, the default is 0.

void initkinematics(treenode datanode [, double x, double y, double z, double rx, double ry, double rz, int managerotation, int localcoords ] )
datanode - This is the blank node for kinematic data. x, y, z - These are optional initial location variables. Defaults: 0, 0, 0 rx, ry, rz - These are optional initial rotation variables. Defaults: 0, 0, 0 managerotation - This optional parameter is either 1 or 0. If 1, the object will always point in the direction of travel. Default: 0 localcoords - This optional parameter is either 1 or 0. If 1, then the object will travel according to its container coordinate system. If 0, then it will travel according to its own coordinate system. Default: 0 This parameter set allows you to explicitly pass initial locations and rotations, instead of referencing an object. Although you would probably more often use the other parameter set where you pass the object in, this parameter set gives you ultimate flexibility. Use this if you want to explicitly pass in the initial locations and rotations of the object, or if your location and rotation values don't necessarily represent real locations and rotations in your model. For example, you are simulating a robot arm, and there are several joints of the arm that move/rotation with different acceleration/deceleration/max speed values. The visualization of movements of the arm are not simulated with explicit FlexSim locations/rotations, but are done using your own draw commands and labels or variables. In this case, you don't want kinematics to be applied to straight rotations and locations, but rather to information that you are keeping on the object yourself. In such situations, a given set of kinematics does not need to be viewed as applied directly to x,y,z locations and x,y,z, rotations, but can rather be viewed as six separate kinematic motions, each along one axis. These six axes can represent whatever you want them to. For example, your robot has four joints, each with one rotation value. To have the four joints of the robot move using kinematics, you can have each joint simulate one axis in the kinematics.

The x part of the kinematics applies to the rotation of joint 1, the y part applies to the rotation of joint 2, the z part applies to the rotation of joint 3, and the rx part applies to the rotation of joint 4. The other two parts of the kinematics, ry and rz, you don't worry about. You can initialize the kinematics with the start rotations of each of your 4 joints, and then add kinematics that apply to each joint individually. Then, when you want to get the joints' current rotation values out later to draw the robot arm in motion, you can use the getkinematics command instead of the updatekinematics command to get the values explicitly, and not have them be applied to an object's location or rotation. These commands will be explained later.

void setkinematicsrotoffset(treenode datanode, double rx, double ry, double rz)


datanode - This is the blank node for kinematic data. rx, ry, rz - These are initial rotation variables. This command would only be used if managerotation is passed into initkinematics as 1. This allows you to set an initial rotation from which the rotation is managed. By default, the object's positive x direction will always point in the direction of the object's current velocity. In the case of a truck, you may want the truck, instead of always being rotated so that it is traveling forward, to travel backward. Here you could specify a rotation offset of (0,0,180).

The addkinematic Command


double addkinematic(treenode datanode, double x, double y, double z, double targetspeed [, double acc, double dec, double startspeed, double endspeed, double starttime, int type ] )
datanode - This is the blank node for kinematic data. x, y, z - These are offset locations or rotations. targetspeed This is the target travel speed. acc - This optional parameter specifies the acceleration. Default: 0 (or infinite acceleration) dec - This optional parameter specifies the deceleration. Default: 0 (or infinite deceleration) startspeed - This optional parameter specifies the initial velocity. Default: 0 endspeed - This optional parameter specifies the ending velocity. Default: 0

starttime - This optional parameter specifies the absolute start time. Default: Current Time type - This optional parameter specifies the type of travel to apply (rotation or travel). Default: KINEMATIC_TRAVEL This command adds a kinematic to the set of kinematics. The x, y, and z parameters make up an offset location or rotation. For example, the location (5,5,0) tells the kinematic to travel 5 in the x and 5 in the y. Note that these are offsets from the object's current position, and not absolute locations. The targetspeed parameter specifies the target speed for the travel operation. The other parameters are optional. Acc specifies the acceleration. Dec specifies the deceleration. Startspeed specifies the speed that the kinematic should start at. If this speed is higher that the target speed, then the object will start at the start speed and decelerate down to the target speed. Endspeed specifies the ending speed for the operation. If endspeed is greater than targetspeed, then at the end of the operation, the object will accelerate from the target speed to the end speed. The starttime is the start time of the kinematic, in simulation time, not as an offset from the current time. The type parameter specifies what type of kinematic it is. This value should either be KINEMATIC_TRAVEL, or KINEMATIC_ROTATE. If it is KINEMATIC_TRAVEL, the operation will be applied to the x, y, and z location values. If it is KINEMATIC_ROTATE, the operation will be applied to the rx, ry, and rz rotation values, and speeds are defined in degrees per unit of time, accelerations/decelerations in degrees per unit of time squared. The command returns the time that this kinematic operation will finish. If optional parameters are not passed into the command, the following defaults apply:

The updatekinematics Command


void updatekinematics(treenode datanode, treenode object [, double updatetime])
datanode - This is the blank node for kinematic data. object - This is the object that will do the moving. updatetime - This optional parameter specifies the absolute update time. Default: Current Time This command should be called in the middle of the kinematic operation, usually on predraw or draw. It calculates and then sets the current location and rotation of the object, according to all kinematics that have been added and the current update time. The updatetime parameter is optional. If it is not passed, the current simulation time is used.

Other Kinematics Commands

double getkinematics(treenode datanode, int type [, int kinematicindex, double updatetime/traveldist])


datanode - This is the blank node for kinematic data. type - This specifies the type of information to retrieve (listed below). kinematicindex - This optional parameter specifies which kinematic to query. Default: 0 (all kinematics) updatetme/traveldist - This optional parameter represents either the update time or the travel distance, depending on the parameter type. Default: Current Time This command is used if you want to get explicit information on the kinematics. You can get information on the entire set of kinematics, or on each individual kinematic. Use this if your kinematics do not apply directly to object locations and rotations, or if you need this information in your logic. The type parameter specifies the type of information you want, and will be explained shortly. The kinematicindex parameter is optional, and specifies which individual kinematic you want to get information for. For example, if you add a kinematic to travel 5 units in the x direction as the second addkinematic command, you would pass a 2 as the kinematicindex parameter into the getkinematics command. If not passed, or if you pass a 0 value here, the default gets information for all kinematics together. The updatetime/traveldist parameter is optional. The meaning of this parameter depends on the type parameter you specify. Sometimes this parameter will not be used. Some of the time it represents the requested update time that you want to get information for. If not passed, the current time is used. In the case of a KINEMATIC_ARRIVALTIME query, this parameter instead represents travel distance. The use of this parameter will be explained with each query type. If you are getting information for all kinematics (kinematicindex is not specified or is 0), then you can pass the following values as the type parameter. KINEMATIC_X, KINEMATIC_Y, KINEMATIC_Z: return the x, y, and z locations that the object will be at for the given time. KINEMATIC_RX, KINEMATIC_RY, KINEMATIC_RZ: return the x, y, and z rotations that the object will be at for the given time. This will only work if rotation is not being managed by the kinematics, but rather you are managing it yourself. KINEMATIC_VX, KINEMATIC_VY, KINEMATIC_VZ: return the x, y, and z velocities that the object will be at for the given time. KINEMATIC_VRX, KINEMATIC_VRY, KINEMATIC_VRZ: return the x, y, and z rotational velocities that the object will be at for the given time. KINEMATIC_NR: Returns the number of kinematics that have been added. Here

the updatetime parameter is not used. KINEMATIC_STARTTIME: This returns the lowest start time of all the kinematics. Here the updatetime parameter is not used. KINEMATIC_ENDTIME: This returns the highest end time of all the kinematics. Here the updatetime parameter is not used. KINEMATIC_VELOCITY: This returns a scalar value of the total velocity for the given time. KINEMATIC_RVELOCITY: This returns a scalar value of the total rotation velocity for the given time. This will only work if you are managing rotations yourself. KINEMATIC_ENDDIST: This returns the distance from the final destination location of all kinematics from the object's initial location. Here the updatetime parameter is not used. KINEMATIC_ENDRDIST: This returns the distance from the final destination rotational position of all kinematics from the object's initial rotational position. This will only work if you are managing rotations yourself. Here the updatetime parameter is not used. KINEMATIC_TOTALDIST: This returns the sum of the distances of all the added kinematics. This has a subtle difference from KINEMATIC_ENDDIST. For example, if your first kinematic travels 10 in the x direction, and your second kinematic travels -10 in the x direction, then the enddist value will be 0, whereas the totaldist value will be 20. Here the updatetime parameter is not used. KINEMATIC_TOTALRDIST: This returns the sum of the rotational distances of all the added kinematics. This will only work if you are managing rotations yourself. Here the updatetime parameter is not used. KINEMATIC_CUMULATIVEDIST: This returns the cumulative travel distance of all added kinematics. This is different than enddist or totaldist; it calculates the distance of the possibly curved path that the object will follow during the entire kinematic operation. Here the updatetime parameter is not used. KINEMATIC_CUMULATIVERDIST: This returns the cumulative rotational travel distance of all added kinematics. This will only work if you are managing rotations yourself. Here the updatetime parameter is not used. KINEMATIC_TOTALX, KINEMATIC_TOTALY, KINEMATIC_TOTALZ: These return the sum of x, y, or z component of all added kinematics. Here the updatetime parameter is not used. KINEMATIC_TOTALRX, KINEMATIC_TOTALRY, KINEMATIC_TOTALRZ: These return the sum of rx, ry, or rz component of all

added kinematics. This will only work if you are managing rotations yourself. Here the updatetime parameter is not used. If you are getting information on an individual kinematic (by passing a kinematicindex parameter greater than 0), you can pass one of the following values as the type parameter. KINEMATIC_X, KINEMATIC_Y, KINEMATIC_Z: These return x, y, or z component of the current location of the specified kinematic at the given update time. For example, if you added a kinematic to travel 10 units in the x, starting at time 5, and you want to know the x location for this given kinematic at time 7, you can call getkinematics(datanode, KINEMATIC_X, index, 7) to get the x location for time 7. KINEMATIC_RX, KINEMATIC_RY, KINEMATIC_RZ: These return the rx, ry, or rz component of the current location of a rotational kinematic at the given update time. KINEMATIC_VX, KINEMATIC_VY, KINEMATIC_VZ: These return the x, y, or z component of the current velocity for the specified kinematic at the given update time. KINEMATIC_VX, KINEMATIC_VY, KINEMATIC_VZ: These return the x, y, or z component of the current rotational velocity for the specified kinematic at the given time if it is a rotational kinematic. KINEMATIC_ENDTIME: This returns the time that the specified kinematic will finish its operation. This is the same endtime that is returned from the addkinematic command. Here the updatetime parameter is not used. KINEMATIC_STARTTIME: This returns the time that the specified kinematic will start its operation. This is the same starttime that you specified when you added the kinematic. Here the updatetime parameter is not used. KINEMATIC_ARRIVALTIME: In this query, the updatetime/traveldist parameter is used as a requested travel distance for the given kinematic. This returns the time of arrival for a certain sub-distance of a given kinematic. For example, if I've added a kinematic that tells the object to travel 5 units in the x direction, but I want to know how long it will take him to travel just 3 of those 5 units, I can use this query, and pass 3 in as the traveldist parameter. KINEMATIC_STARTSPEED: This returns the start speed for the kinematic. This is the startspeed you specify in the addkinematic command. Here the updatetime parameter is not used. KINEMATIC_ENDSPEED: This returns the end speed for the kinematic. This is usually the endspeed that you specify in the addkinematic command, but may not be if the kinematic cannot decelerate/accelerate to your specified endspeed given the distance it has to travel. Here the updatetime parameter is not used.

KINEMATIC_ACC1: This returns the acceleration value used to get from the start speed to the target speed. If the start speed is less than the target speed, then this value will be the acceleration value. Otherwise it will be the negative deceleration value. Here the updatetime parameter is not used. KINEMATIC_ACC2: This returns the acceleration value used to get from the target speed to the end speed. If the end speed is less than the target speed, then this will return the negative deceleration value. Otherwise it will return the acceleration value. Here the updatetime parameter is not used. KINEMATIC_PEAKSPEED: This returns the peak speed or "reached speed" for the kinematic. This is usually the same as the target speed specified in the addkinematic command, but may not be if the kinematic cannot get to the target speed given the distance it has to travel. Here the updatetime parameter is not used. KINEMATIC_ACC1TIME: This returns the total time the kinematic will spend accelerating/decelerating from the start speed to the target speed. Here the updatetime parameter is not used. KINEMATIC_PEAKTIME: This returns the total time the kinematic will spend traveling at the peak speed. Here the updatetime parameter is not used. KINEMATIC_ACC2TIME: This returns the total time the kinematic will spend accelerating/decelerating from the target speed to the end speed. Here the updatetime parameter is not used. KINEMATIC_TOTALDIST: This returns the total distance for the kinematic operation. KINEMATIC_TOTALRDIST: This returns the total rotational distance for the kinematic operation if it is a rotational kinematic. KINEMATIC_TOTALX, KINEMATIC_TOTALY, KINEMATIC_TOTALZ: These return the x, y, or z component of the total distance for the kinematic operation. These are the same values you passed into the addkinematic command. Here the updatetime parameter is not used. KINEMATIC_TOTALRX, KINEMATIC_TOTALRY, KINEMATIC_TOTALRZ: These return the x, y, or z component of the total rotational distance for the kinematic operation if it is a rotational kinematic. These are the same values you passed into the addkinematic command. Here the updatetime parameter is not used. KINEMATIC_VELOCITY: This returns the total velocity of the kinematic for the given time. KINEMATIC_RVELOCITY: This returns the total rotational velocity of the kinematic for the given time if it is a rotational kinematic.

KINEMATIC_TYPE: This returns KINEMATIC_TRAVEL if the specified kinematic is a travel operation, and KINEMATIC_ROTATE if the kinematic is a rotate operation.

void profilekinematics(treenode datanode [, int index ])


datanode - This is the blank node for kinematic data. index - This optional parameter specifies the index of a specific index to print information for. Default: 0 (all kinematics) This command prints kinematic information to the output console. The index parameter is optional. If it is not passed, then information will be printed for all kinematics that have been added. If it is passed, then the index variable is an index of the added kinematic you want to print information for.

void deactivatekinematics(treenode datanode)


datanode - This is the blank node for kinematic data. This command tells the kinematic to not update locations when the updatekinematics command is called. Execute this on reset to free the object to move it around in the ortho view.

Ports
Every FlexSim Healthcare object has an unlimited number of ports through which they communicate with other objects. There are three types of ports: input, output, and center. Input and output ports are used in the routing of Patients or Items. For example, Patients may need to be able to move from a Patient Arrivals object to get to a Patient Processing object, configured as a Registration Desk. To simulate this, you would need a connection from the output ports of Patient Arrivals object to the input ports of the Registration Desk, meaning once the Patient has been created by the Patient Arrivals object, it is released and allowed to travel to the Registration Desk. These types of output to input port connections are largely handled automatically through the use of the Flowcharting tool. The necessity of the ports is one of the reasons why Flowcharting is so important to building a model. Item objects also make use of output to input port connections to govern the flow of Items. Port connections for Patient and Item class objects can also be managed from the Connections tab of an object's Properties Window. Due to the number of ports that are often needed to connect the objects of one Area with another, Port connections are hidden in the 3D view by default but can be shown via the right-click menu. Center ports are a more advanced feature used to create references from one object to another. A common use for central ports is for referencing resources such as Staff or Equipment to other objects such as Patient Processing objects. Center port connections used in this manner are used in conjunction with Picklist options in the Advanced Functions of the Track Manager that are specifically designed to use them . Center ports are not created automatically, and are made available to advanced users to more easily accomplish certain modeling ends. Any type of Port can be created and connected manually in the following way: Click on one object and drag to a second object while holding down different letters on the keyboard. If the letter 'A' is held down while clicking-and-dragging, an output port will be created on the first object and an input port will be created on the second object. These two new ports will then be automatically connected. Holding down the 'S' key will create a central port on both objects and connect the two new ports. Connections are broken and ports deleted by holding down the 'Q' for input and output ports and the 'W' key for central ports. The following table shows the keyboard shortcuts used to make and break the two types of port connections.

Output - Input Disconnect Q Connect


A

Center
W S

Note: Though you can create input to output ports manually as described above, it is still recommended to let the Flowcharting tool manage your connections for you. Advanced users may find it helpful to manually manage some connections under specific modeling scenarios but for the most part, it should be unnecessary.

Miscellaneous Concepts
1. 2. 3. 4. 5. 6. FlexSim Tree Structure State List Kinematics FlexSim XML Advanced Undo Ports

State List
Below is a list of state numbers and their respective macros. Whenever you write code that has to do with setting the state of objects, like using the stopobject() command or the utilize task, you can substitute these macros in for the number. Refer to the library objects for more information about what each state means to each object. 1 - STATE_IDLE 2 - STATE_PROCESSING 3 - STATE_BUSY 4 - STATE_BLOCKED 5 - STATE_GENERATING 6 - STATE_EMPTY 7 - STATE_COLLECTING 8 - STATE_RELEASING 9 - STATE_WAITING_FOR_OPERATOR 10 - STATE_WAITING_FOR_TRANSPORTER 11 - STATE_BREAKDOWN 12 - STATE_SCHEDULED_DOWN 13 - STATE_CONVEYING 14 - STATE_TRAVEL_EMPTY 15 - STATE_TRAVEL_LOADED 16 - STATE_OFFSET_TRAVEL_EMPTY 17 - STATE_OFFSET_TRAVEL_LOADED 18 - STATE_LOADING 19 - STATE_UNLOADING 20 - STATE_DOWN 21 - STATE_SETUP 22 - STATE_UTILIZE 23 - STATE_FULL

24 - STATE_NOT_EMPTY 25 - STATE_FILLING 26 - STATE_STARVED 27 - STATE_MIXING 28 - STATE_FLOWING 29 - STATE_ALLOCATED_IDLE 30 - STATE_OFF_SHIFT 31 - STATE_CHANGE_OVER 32 - STATE_REPAIR 33 - STATE_MAINTENANCE 34 - STATE_LUNCH 35 - STATE_ON_BREAK 36 - STATE_SUSPEND 37 - STATE_AVAILABLE 38 - STATE_PREPROCESSING 39 - STATE_POSTPROCESSING 40 - STATE_INSPECTING 41 - STATE_OPERATING 42 - STATE_STANDBY 43 - STATE_PURGING 44 - STATE_CLEANING 45 - STATE_ACCELERATING 46 - STATE_MAXSPEED 47 - STATE_DECELERATING 48 - STATE_STOPPED 49 - STATE_WAITING 50 - STATE_ACCUMULATING

3D Media
1. 2. 3. 4. 5. 6. Importing 3D Media Preparing a 3D File Importing AutoCAD Drawings Level Of Detail Transparency Preload Media Tool

Import Media Files


This editor allows you to add 3D shapes and images to be pre-loaded to the model, as well as get the path string for shapes that are already loaded. You will usually only need to use this editor if you are dynamically changing the shape of objects during the simulation. Otherwise, just select a shape from an object's Properties window.

To work in this editor, select either Shapes or Images from the drop-down box at the top. Then select a shape from the second drop-down box. When you select a shape, the text box updates its text to show the path of the currently selected object. To add a new object, click the Browse button, find the .3ds, .wrl, .dxf, or .stl file for shapes, or a .bmp or .jpg file for images, and click Open. Then press the Add button to add the 3D object or image to the pre-loaded list. Press the Delete button to remove shapes that have been added to the list. The number next to each option in the drop-down list can also be used if you are writing code that references a texture or shape index.

Importing 3D Media
FlexSim can import several types of 3D media. These include 3ds, wrl, dxf, and stl file types. You can import media using two methods. First, and most common, you can import media by selecting a 3D file from an object's visual properties page. Second, if there are some 3D media files that are not used by any model objects by default, but you want to change their 3D representation dynamically during the simulation run to use these 3D media files, you can use the media importer to import media files explicitly. The following are some hints and suggestions for importing media correctly. Note on importing wrl files: FlexSim will only import VRML version 1.0 shapes, not version 2.0. Note on importing stl files: FlexSim will only import stl ascii files, not stl binary files.

Using Shape Factors


Each media file that is imported has certain scaling and offset settings which may cause the 3D model that you import to not fit within the object's boundaries. In this case, edit the object's 3D shape factors from its visual properties window to fit the 3D shape within the object's yellow bounding box.

Letting Color Show Through the 3D Object


Often, when you design your own 3D files or get them from the internet, they will have materials and colors predefined with the 3D model. If materials are defined on a 3D object that is imported into FlexSim, those materials will show through, instead of the object's color defined in FlexSim. If you want the object's FlexSim color to show through the 3D object, you will need to change the ordering of the 3D file accordingly. In the 3D file, the polygons whose FlexSim color shows through must be defined before any material is defined in the file. This can be tricky to do, and depends on the 3D modeling program that you are using.

3D Frames
You can animate an object using 3D frames. For any 3D file, you can specify frames of that 3D file by creating different 3D models, and saving them as <original file name>FRAME<frame number>.3ds. For example, the operator's primary 3D file is Operator.3ds. This is drawn if its frame is set to 0 using the command setframe(current, 0). Its other frames are defined in OperatorFRAME1.3ds, OperatorFRAME2.3ds, etc. If you call setframe(current, 3), then the operator will

draw the 3D file specified in <original filename>FRAME3.3ds, etc.

Level of Detail
You can specify several levels of detail for a given 3D file. This can significantly increase the speed of drawing the model. As you get further away from objects, they are drawn with less detail, thus increasing speed.

Importing AutoCAD Drawings


The following steps should be performed when preparing an AutoCAD .dxf file for import: 1. Remove all unnecessary information: AutoCAD files typically include much information that is unnecessary to the simulation. Typically, all a simulation needs is a basic layout. Removing information that is extraneous to the simulation will make your model more clear and reduce the burden on your graphics card. As a result it will be easier to build and present the model. Remove any parts of the drawing that are not pertinent to the simulation study. 2. Adjust the scale to FlexSim units: AutoCAD files are often scaled in inches. FlexSim models are often scaled in feet or meters. It is important that the AutoCAD file be rescaled to work appropriately in FlexSim. For instance, to convert from an AutoCAD file in inches to a FlexSim model in feet, the scale factor will be 1/12. To determine how much to scale, follow these steps: Measure a known distance in AutoCAD ("_dist"). Apply the following equation: scale factor = FlexSim distance / ACAD distance. To scale objects in AutoCAD follow these steps: Select the objects you want to scale. Type "_scale" in the command prompt or select the scale command from the menus. Specify a reference point. Type in the calculated scale factor in the command prompt. 3. Move objects to the origin: AutoCAD drawings are usually drawn using a specific coordinate system. This usually means that the objects are not located near the origin (0,0,0). When a .dxf file is imported into FlexSim, it is positioned in FlexSim's coordinate system according to the .dxf's positioning. So if the origin point of your AutoCAD file is very far away from the actual drawing, when that .dxf file is imported into FlexSim, the layout will also be very far away from the model's origin position in FlexSim. This can be quite frustrating for the modeler. For this reason, move your AutoCAD objects to the origin. Do so by completing the following steps: 1. Select the objects you want to move. 2. Type "_move" in the command prompt or select the move command from the menus. 3. Specify a reference point. 4. Type in the desired location of that point in the command prompt. 4. Explode compound objects. FlexSim can only import basic shapes, so it is important to explode any compound objects in the AutoCAD drawing into their basic shapes. To explode compound objects in AutoCAD follow these steps: 1. Select the objects you want to explode. 2. Type "_explode" in the command prompt or select the explode command from the menus. 3. Repeat the above steps until there are no objects that were exploded.

In FlexSim: 1. Go to the Floor Plan Button: promted by the wizard. Alternatively you may also: 1. Create a Graphic Display. Open its Properties Window will open automatically. 2. Select "Imported Shape" for the Visual Display. 3. Select the AutoCAD file onyou want to import in the "Filename" field. and step through the steps as

Level Of Detail (LOD)


LOD files are 3D shapes that get progressively simpler and that are tied together by a common name: file.3ds / fileLOD1.3ds If an object uses a 3D shape that has LOD then the 3D shape that the object displays is dependent on how far that object is from the view's camera position. 0 is the base LOD file.3ds 1 is the 2nd LOD fileLOD1.3ds 2 is the 3rd LOD fileLOD2.3ds N is the nth LOD fileLODn.3ds LOD Files are used to show higher level objects when the viewer is close up and lower level objects when the viewer is farther away. LOD improves the speed at which a model will display in the view window. LOD allows for the use of more polygon intensive 3D shapes by displaying only a few high polygon count shapes at any given time.

Preparing LOD Files


To prepare a group of 3D Shapes for use as an LOD file do the following: 1. Gather together two or more shapes that you want to use as LODs of the same object. 2. Get the LOD files saved as the same file type (3ds, wrl). 3. Make sure that each LOD uses or at least isn't disfigured by the base file's .xds file (each frame can have it's own .yds file). 4. Name the LOD files appropriately. The first file is the name.3ds or name.wrl. Each successive file is nameLOD#.3ds or nameLOD#.wrl. For example,

Queue.3ds, QueueLOD1.3ds, QueueLOD2.3ds, etc. To import and LOD shape just follow the steps used in the section on Importing 3D Media. Use the base object for the name of the file that you select.

LDS/LRL Files
lds / lrl files are used to determine the distances at which the different LOD's will be shown. lds / lrl files must have the same names as the objects they modify: crane.3ds crane.lds crane.wrl crane.lrl

lds / lrl file info


The lrl/lds file is a text file made up of three numbers separated by new lines: The range perspective value, the range perspective mode, and the range ortho value.

The range perspective value is the distance value at which the LOD files will change in the perspective window. The range perspective mode value is either 1 or 0. 0 means linear (slightly faster). 1 means inverse distance (more coverage at farther distances). The range ortho value is the distance value at which the LOD files will change in the ortho window.

We suggest using AC3D for 3D media creation. A license is relatively cheap and AC3D has a lot of capability coupled with a pretty UI that's pretty quick to learn. You can get AC3D from www.inivis.com. We also suggest exporting media to the 3DS file format. The 3DS file format allows for very fast drawing speeds, fast load speeds, and there are several "hidden features" that FlexSim has made available for the 3DS file format, including bleeding the FlexSim object's color through on certain parts of the shape, using the FlexSim object's defined texture instead of the texture defined in the 3DS file, auto-scaling the FlexSim object based on 3DS file dimensions, etc. The following steps should be performed when preparing a 3D file for Import:

Reduce the Number of Polygons


3ds and wrl files typically include more information than is necessary. Removing excess polygons will improve the visual performance of your model. As a result, it will be easier to build and present the model.

Textures vs. Polygons


The use of well made textures can help a modeler reduce the number of polygons required to make a realistic looking object. Below are some pictures of low polygon 3D files in FlexSim. Also, where possible you should consolidate objects in your 3D creation software and share the same texture among multiple objects. This reduces the number of OpenGL state changes required, which can significantly improve performance.

Adjust the Scale


3D files are not necessarily drawn in feet or meters and may need to be rescaled to work appropriately in FlexSim. There are three ways to adjust the scale of a 3D file: 1. Appropriately scale the file in the 3D program. 2. Scale the visual tool or other object that the file is imported into. 3. Use an xrl file for wrl files. If you are exporting to 3DS, then you can just make sure the object is scaled properly in AC3D or whatever package you use, then import it into FlexSim, and it will automatically import to the correct size. Just make sure that your units in AC3D are the same as the units you are going to use in FlexSim.

Getting the Object's Color to Bleed Through


For 3DS files, you can have the FlexSim object's color bleed through on certain shapes in the 3DS file. To do this, in AC3D give the object an ambient color value of rgb:(0.235,0.235,0.243). Also, you'll need to make sure the object gets exported as first in the 3DS file definition. AC3D's 3DS export sorts all objects alphabetically by their name, so you should give the object a name that is alphabetically before any other objects in the model.

Getting the Object's Texture to Bleed Through


For 3DS files, you can also have the FlexSim object's defined texture show up on the shape instead of the texture defined in the 3DS file. To do this, just add a texture

named "fstx.png" to the object in AC3D. Again, make sure the object is named alphabetically before all other objects in the model.

XRL Files
xrl files are used to make imported wrl shapes conform to the object they are imported into. xrl files must have the same names as the objects they modify: crane.wrl crane.yrl

xrl file info


Spatial values determine the end size of the 3D shape. Offset values are the values required to get the 3D shape zeroed out and sized to 1,1,1. The centroid value is 1 or 0 and determines if the object rotates around the center of the object or the top left corner.

xrl file makeup


The xrl file is a text file made up of 13 values separated by carriage returns. You can edit this file using notepad or wordpad, as shown below.

YDS
yds files are used to make imported 3DS shapes look good. yds files must have the same names as the objects they modify:

crane.3ds crane.yds

yds file info


The yds file is a text file made up of 3 values separated by carriage returns. You can edit this file using notepad or wordpad, as shown below.

1. The luminous value determines whether the 3D shape will be affected by FlexSims lighting. 2. The backfacecull value determines whether FlexSim will draw both sides of each polygon or not. If the imported shape looks backwards or odd, set this value to 1. 3. The creaseangle value is the angle at which FlexSim will stop smoothing the corners of the 3D shape.

Importing a 3D File into FlexSim


To import a 3D file into FlexSim follow these steps: 1. 2. 3. 4. Create a Visual Tool. Select Imported Shape for the Visual Display. Select the 3D file you want to import in the Filename field. Set the minimum magnification (usually 0 unless you want the drawing to disappear at a certain magnification). 5. Set the maximum distance (usually 100000 unless you want the drawing to disappear when you move the view away from the drawing). To change the shape of an existing object follow these steps: 1. Go to the Properties page of an object. 2. Select the 3D file you want to import in the 3D shape field.

Transparency
You can add transparency to your 3D objects by using .tmp and .tpg file types. .tmp and .tpg files are grey scale files that determine the transparency of a corresponding .bmp or .jpg file. For the .tmp or .tpg files white is opaque and black is transparent with all of the shades of grey in between being semi-transparent. The name of the texture and transparent file must correspond to the original .bmp or .jpg file, and it must be in the same directory as well. For example, if the texture FlexSim.bmp is used, and there is also a FlexSim.tmp file in the same directory, then the .tmp file will be used to specify transparency in the texture.

Note on object rank and transparency: The rank of an object has a direct effect on the way the transparency of that object will look. All of the objects that are ranked higher in the model than the transparent object will not appear behind the transparent object.

General Windows
1. 2. 3. 4. Find Replace Global Preferences Window Tree Browse Dialog Table Editor

Attribute Hints
The attribute hints window shows the list of special FlexSim attributes and their meaning. Click inside the window and start typing the name of an attribute you would like to know about to have the window will automatically scroll to that attribute.

Find Replace
The find/replace dialog is used to search for and/or replace text or numbers in the tree.

Find what - Type here the text or number you would like to find, and then click the Find button. Replace with - Enter the text you want to replace, and then click the Replace button. Starting Object - This is a path reference to a node from which to start the search. You can type the path in explicitly or browse for the node using one of the three

browse buttons on the right, which will bring up a tree browse dialog. Search Only Toggled Nodes - This option restricts the search to nodes containing Flexcript or C++ code.

Output
Once you click on the Find or Replace button, the results of the operation will appear, reporting information on the locations of data that was found and/or replaced.

General Windows
1. 2. 3. 4. Find Replace Global Preferences Window Tree Browse Dialog Table Editor

Global Preferences Window


The global preferences dialog window specifies default user preferences for FlexSim. These preferences are saved across several models and remembered when FlexSim is closed and reopened. The dialog window is split into four tabs.

Fonts and Colors


The Fonts and Colors tab specifies syntax highlighting and other settings used in FlexSim's implementation of the Scintilla code editor. You can also specify settings and colors for the template editor, as well as for unformatted text (which is used in multi-line unformatted text controls like the user description portion of the Properties window).

For more information on the Scintilla code editor, go to www.scintilla.org. The Scintilla text editor is under copyright 1998-2003 by Neil Hodgson <neilh@scintilla.org>. All

Rights Reserved.

Environment

In this tab page you can specify various settings such as whether you want code to be C++ or Flexscript by default, various grid settings in the ortho and perspective view, excel DDE settings, etc.

User Libraries

This tab page lets you specify a set of user libraries to be loaded when FlexSim starts up. The paths specified are relative to your Flexsim6/libraries directory.

Customize Toolbar

In this tab page you can customize which menu commands are accessible easily through the customizable section of the top toolbar.

Graphics

This tab is used for customizing graphics settings so that FlexSim will run the best on your hardware. If FlexSim is having a hard time rendering the graphics, check the Compatibility Mode box and see if that helps. A restart of FlexSim is required after any changes have been made.

Compiler

This tab lets you set up your compiler

Table Editor
The table editor is used to edit a simple table in FlexSim.

Name - This is the table's name. It should be memorable and describe the table's function. The commands to read and write to them access them by name. Rows - This is the number of rows in the table. After changing it, press Apply to update the table on-screen. Any new rows that were created can now be edited. Columns - This is the number of columns in the table. After changing it, press Apply to update the table on-screen. Any new columns that were created can now be edited.

Editing the Table


To edit a cell in the table, click on the cell and type the data in the cell. Press the arrow keys to navigate between cells. Cells hold numbers by default, but can be set to hold string data by right-clicking on the cell and selecting Assign String Data.

Tree Browse Dialog


This dialog allows you to browse for a node in the tree. The purpose of selecting a node is dependent on the context of the situation. Sometimes you will use this window to select a start node for a find/replace operation. Sometimes you will use this window to select an experiment variable in the Experimenter. Select the node you want by clicking on it in the tree view, then click on the Select button. The window will then close and return to the original calling window.

Picklists

You will find picklist windows throughout FlexSim. These windows give you an easy interface for implementing functionality in FlexSim. Behind the scenes, each of these windows refers to a piece of code. The nice thing about these picklist interfaces is that they allow you to write functionality without writing code. They give you a list of commonly used functionality when you click on the drop-down box. You can also select the text and replace it with a constant or an expression.

Popups
Many picklist options use popups. Popups allow you to easily edit the option parameters. You can edit these options at any time by clicking the popup to close it. button. Once you have entered the values you want in the popup, click anywhere outside the

Code Template
Some picklist options use code templates. You can edit these options by clicking on the code template button . This shows a popup explaining what the selection does. It also allows you to enter your own information for specific parameters

highlighted in blue.

In the above example, the "By Global Table Lookup" option was selected in the drop down box. The code template window tells you that the value in the table named "labelname", row getitemtype(item), column 1, will be used as the setup time for Processor1. Again, when you select a picklist option and edit the code template window, behind the scenes you are really creating your own segment of code. The nice thing about it, though, is that you only need to specify a minimal amount of information. You don't really have to write code.

Code Edit
Experienced modelers also have the ability to write the code explicitly when needed. By clicking on the code edit button , you can bring up the code edit window, in which you can see all of the code that implements this field. Note that much of the code you will see is actually used to format the code template window. You can decipher the real code from the code template formatting code by the color. Code template formatting code is commented out in gray.

Within the code window, you can specify whether you want your code to be interpret ed as Flexscript or compiled as C++ (in which case you will need to compile your model). You can also check the Flexscript syntax by pressing the button. You can also view the code in a logic form by pressing the button. For more information on how to write code in FlexSim, refer to writing logic in FlexSim.

DLL Functionality
You can also specify the given field as accessing a function from a dll. In this case you would not provide the code as the text, but would provide the path to the dll as well as the name of the function to call. To create such dll you would need to use a special Visual C++ project. This project is available on the user community. The code field itself will need to specify two strings, each enclosed in quotes. The first string is the path to the dll. The second string is the name of the function. When you press the DLL radio button a message will appear that will let you create a template specifying the two strings.

Locking Code
There is also a "Locked" checkbox at the bottom of the view. This checkbox should only apply to Flexscript or C++ code. It lets you lock the code state of the field to either Flexscript or C++. We provide this option so that modelers can have both the ease of use of Flexscript (code works immediately when editing in Flexscript, without having to compile) as well as the run-speed of C++ (since it is compiled, it runs much faster than Flexscript). While in the model building phase you can use Flexscript, so that your code is interpreted immediately after you write it. Then, once your model is ready to run, you can choose the Build|Make all code C++ option, compile, and run to get the speed of C++. However, there may be some code that you write that cannot be converted from Flexscript to C++ or vice versa because it uses features specific to that language. In this case you would check the Lock checkbox to lock the code state of the given field, so that when you choose the Make all code C++ or Make all code Flexscript menu option, that field will not be switched over.

Triggers
The interface for object triggers is slightly different than for standard pick lists. Here there are two buttons instead of a drop down box.

The button erases all code for the trigger. The button opens a drop-down menu where you can select a trigger option to add to the trigger. The other button works the same as with regular pick lists.

Break To ("Break To" Requirement)


Overview:
Define what type of tasksequences this object will accept during a "break" task in its active tasksequence. A standard tasksequence is made up of a travel - load - break travel - unload sequence of tasks. This field will only be evaluated when the TaskExecuter performs a "break" task. When the TaskExecuter receives a "Break" task, this is a notification that it may now put the currently active task sequence back in its queue and see if there are any other task sequences that it might want to do before it finishes the current one. This allows for capabilities such as loading several items before dropping them off. In such a case, the TaskExecuter will first make a check to make sure it is currently capable of "multitasking." This is done by asking "is my content less than my capacity?" If the check is true, then it will execute this code to find a tasksequence to break to. If this code returns NULL, then it will not break at all. If a valid tasksequence numeric pointer is returned, then it will break to the new tasksequence and begin executing it. When finished with new tasks, it will return to the original tasksequence.

Access variables:
tasksequence: a reference to the tasksequence that I'm checking current: the current object

Creation Trigger (On Creation)


Overview:
This code is executed when a flowitem is first created.

Access variables:
current: the current object item: the object that was just created rownumber: the row number of the arrival (if one applies)

End of Run (End of Replication)


Overview:
This function is executed at the end of each replication run. The replication ends when the model has run out of events or the simulation end time has expired.

Access variables:
replication: current replication number scenario: current scenario number

End of Scenario
Overview:
This function is executed after the last replication of each scenario.

Access variables:
replication: current replication number scenario: current scenario number

End of Warmup (End of Warmup Period)


Overview:
This function is executed at the end of the user-defined warmup time for each replication run. The time and system variables are reset, but the flowitems remain where they are.

Access variables:
replication: current replication number scenario: current scenario number

Entry/Exit Trigger (On Entry/On Exit)


Overview:
Entry Trigger: This function is executed each time a flowitem enters this object. Exit Trigger: This function is executed each time a flowitem exits this object. Note on entry/exit trigger context: Generally, the entry and exit triggers are executed at the very beginning of the OnReceive/OnSend event of an object, before any other logic is executed. This means that you can change the object's variables, labels, etc., and have those changes be applied correctly within the event logic. However, executing commands that may affect further events of the object should not be executed in the entry/exit trigger, because some events have yet to be created in the event logic of the object, and functions which affect the object's events should wait until those events have been created. In such a case you should send the object a delayed message in 0 time (using the senddelayedmessage() command), and then execute the functionality from the message trigger. This allows the object to finish the rest of its event logic before your commands are executed. Commands which apply in this setting are stopobject(), requestoperators(), openoutput(), openinput(), resumeinput(), resumeoutput(), and in some cases the creating and dispatching of task sequences, depending on the types of tasks that are in them.

Access variables:
current: the current object item: the involved object that just entered/exited port: the number of the port that the object came/left through

Experimentation
1. 2. 3. 4. 5. 6. 7. 8. End of Experiment End of Run End of Scenario End of Warmup Performance Measure Start of Experiment Start of Run Start of Scenario

Item Objects
1. 2. 3. 4. 5. 6. Pick Operator Pull Requirement Pull Strategy Send To Port Split Quantity Transport Dispatcher

Load/Unload Time
Overview:
Load Time: Returns the value of the load time. The flowitem is moved into the TaskExecuter at the end of the load time. Unload Time: Returns the value of the unload time. The flowitem is moved into the station at the end of the unload time.

Access variables:
current: the current object item: the involved flowitem station: the object where the flowitem is being loaded or unloaded

Load/Unload Trigger (On Load/On Unload)


Overview:
Load Trigger: This trigger is fired once the TaskExecuter has finished its loadtime and just before it moves the flowitem into the TaskExecuter. Unload Trigger: This trigger is fired once the TaskExecuter has finished its unloadtime and just before it moves the flowitem into its destination.

Access variables:
item: the item that is about to be loaded/unloaded current: the current object

Message Trigger (On Message)


Overview:
This function is executed when a message is sent to this object by the sendmessage or senddelayedmessage commands. Each command may pass up to three user-defined parameters.

Access variables:
current: the current object msgsendingobject: the object that sent the message msgparam(1): the message's first value parameter msgparam(2): the message's second value parameter msgparam(3): the message's third value parameter

Mobile Resources (Patients, Staff, Transports, Equipment)


1. Break To Requirement 2. Pass To 3. Queue Strategy

OnDraw Trigger (Custom Draw Code)


Overview:
This function is executed prior to the object's OnDraw Event. It is used to perform user-defined drawing commands and animation. If this function returns 1, the object's standard OnDraw function is not called. If it returns 0, OnDraw occurs normally. FlexScript, C++, and/or OpenGL code can be used to define what is drawn.

Common Commands:
drawcolumn(xloc,yloc,zloc,nrsides,baseradius,topradius,height,xrot,yrot,zrot,red,green,blue[,opacity,texture,xrep,yrep]) drawcube(xloc,yloc,zloc,xsize,ysize,zsize,xrot,yrot,zrot,red,green,blue[,opacity,texture,xrep,yrep]) drawcylinder(xloc,yloc,zloc,baseradius,topradius,height,xrot,yrot,zrot,red,green,blue[,opacity,texture]) drawdisk(xloc,yloc,zloc,innerradius,outerradius,startangle,sweepangle,xrot,yrot,zrot,red,green,blue[,opacity,texture]) drawline(view,x1,y1,z1,x2,y2,z2,red,green,blue) drawobject(view,shape,texture) drawrectangle(xloc,yloc,zloc,length,width,xrot,yrot,zrot,red,green,blue[,opacity,texture,xrep,yrep]) drawsphere(xloc,yloc,zloc,radius,red,green,blue[,opacity,texture]) drawtext(view,text,xloc,yloc,zloc,xsize,ysize,zsize,xrot,yrot,zrot,red,green,blue) drawtomodelscale(object) drawtoobjectscale(object) drawtriangle(view,x1,y1,z1,x2,y2,z2,x3,y3,z3,red,green,blue) spacerotate(x,y,z) spacescale(x,y,z) spacetranslate(x,y,z)

Access variables:
current: the current object view: the view that the object is being drawn in

OnResourceAvailable
Overview:
This trigger is available for either a Dispatcher or a TaskExecuter and behaves a little differently on each. For a Dispatcher, the trigger is fired whenever a downstream TaskExecuter becomes available. For a TaskExecuter, the trigger is fired whenever that TaskExecuter finishes a task sequence. If the TaskExecuter is also a Dispatcher, meaning it has a team that it dispatches tasks to, then the trigger will be fired for both cases. If the function returns a 0, the Dispatcher/TaskExecuter will do its own dispatching logic. If the function returns a 1, the Dispatcher/TaskExecuter will not do anything, and assumes all dispatching logic is done with this trigger using the movetasksequence() and dispatchtasksequence() commands.

Access variables:
current: the current object port: for a Dispatcher, this is the output port of the Dispatcher; for a TaskExecuter that has just finished a task sequence the port value is 0 resource: for a Dispatcher, this is the downstream resource that has become available; for a TaskExecuter, this value is the TaskExecuter itself (or the same as current) nextts: this value is the next task sequence in the task sequence queue lastts: for a Dispatcher, this value is always NULL; for a TaskExecuter, this value is the task sequence that was just completed before it became available

Pass To
Overview:
This function is fired when the Dipatcher receives a task sequence, and should return the output port that the Dispatcher will pass the tasksequence to. If 0 is returned, the tasksequence will automatically queue up according to the defined Queue Strategy until the tasksequence can be passed to an available Dispatcher or TaskExecuter. If a value greater than 0 is returned, the tasksequence will be sent immediately to the returned port number. If a value of -1 is returned, then the Dispatcher does nothing, but rather assumes all dispatch logic is done within the passto function using the movetasksequence() and dispatchtasksequence() commands.

Access variables:
tasksequence: a reference to the tasksequence node current: the current object

Performance Measure
Overview:
This function is called at the end of each replication of a scenario, and returns a performance measure value to be recorded for the current replication.

Access variables:
There are no access variables for the performance measure function. Use model() as a starting point.

Pick Operator
Overview:
This function returns a reference to a dispatcher (or operator) that the operator request will be sent to. The return value must be cast into a number, because the function is hard-coded to return a double. There are also additional return value options for this picklist: If the field returns 0, then the Processor will call no operators. If the field returns -1, then the Processor will call no operators, but it will also call this function again at the time that it is ready to release operators. When the function is called again, the Processor will pass PICK_OPERATOR_PROCESS_RELEASE or PICK_OPERATOR_SETUP_RELEASE as the trigger parameter, depending on whether it is the setup or process step. This allows you to explicitly create task sequence(s) for calling operators, and then explicitly release them at the end, all from within the same code field. For an example of this, look at the code for the "Multiple Teams" option in the picklist.

Access variables:
current: the current object item: the involved flowitem trigger: the involved trigger. Possible values are PICK_OPERATOR_PROCESS, PICK_OPERATOR_SETUP, PICK_OPERATOR_PROCESS_RELEASE, PICK_OPERATOR_SETUP_RELEASE.

Picklists
1. 2. 3. 4. 5. 6. Picklists Triggers Time Picklists Item Objects Mobile Resources Experimentation

Process Finish Trigger (On Process Finish)


Overview:
This code is executed each time a flowitem finishes its process time.

Access variables:
current: the current object item: the object that has finished its process time

Process Time
Overview:
This function returns the process time for the processing object.

Access variables:
current: the current object item: the involved flowitem For a list of pick options, see Time Picklists

Pull Requirement
Overview:
This field is a boolean expression returning either true (1) or false (0). It is evaluated in the OnInOpen event of this object whenever an input port becomes ready. An input port is ready when it is open AND the upstream output port that it is connected to is open. The connection becomes ready when either the input port is opened, OR the upstream output port is opened (assuming the paired port is already open). This Pull Requirement expression will be evaluated for each ready flowitem within the object connected to the input port which just became ready causing the OnInOpen event to fire. If the expression returns a true (1), then the ready flowitem will be pulled in through the ready input port.

Access variables:
current: the current object item: the ready flowitem for which the Pull Requirement is currently being evaluated port: the number of the input port that became ready

Pull Strategy
Overview:
When this object is in pull mode and it is ready to receive its next flowitem, it will first evaluate this Pull From Port field to determine which input port to open. If the Pull From Port field returns a zero (0) for the input port number, then it will open all of its input ports. When an input port is opened, the OnInOpen event of this object will execute immediately if the connected upstream output port is already open, or the OnInOpen event will fire in the future when the upstream output port is eventually opened. When the OnInOpen event fires, the PullRequirement will be evaluated, determining which flowitem will actually get pulled in.

Access variables:
current: the current object

Queue Strategy
Overview:
When the Dispatcher receives a tasksequence, and the "Pass to" function returned a 0, then when a new tasksequence enters the Dispatcher's queue, the Dispatcher goes through his queue of tasksequences, and executes this same function on each tasksequence, and compares it with the value returned for the tasksequence just received. The new tasksequence will then be sorted from highest to lowest (highest value returned will be sorted to the front of the tasksequence queue) according to the value it returned in this function.

Access variables:
tasksequence: a reference to the tasksequence node current: the current object

Reset Trigger (On Reset)


Overview:
This function is executed when the model is reset.

Access variables:
current: the current object

Send To Port
Overview:
This field is evaluated once for each flowitem at the time the flowitem is ready to be sent to the next object. In a Processor object, the flowitem is ready to be sent at the end of its processing time. In a Queue, the flowitem is ready to be sent after the batch has accumulated and has been released. The SendToPort expression must return a valid output port number. The output port will be opened, and the port number will be assigned to the flowitem. The flow item will then be pushed (or pulled) when the port connection becomes ready (output port and connected downstream input port are open). In the special case where the SendToPort expression returns a 0, all output ports will be opened, and the flowitem may leave through the first ready port. If the object is configured to reevaluate sendto, then this field is also evaluated every time a downstream object becomes ready to receive a flowitem. If the function returns a -1, then the flowitem will not be released at all, and should be released later on using the releaseitem() command, or should be moved out using the moveobject command.

Access variables:
current: the current object item: the object that is ready to be sent

Setup Time
Overview:
This function returns the setup time for the processing object.

Access variables:
current: the current object item: the involved flowitem port: the port the product came in through For a list of pick options, see Time Picklists

Split Quantity (Split/Unpack Quantity)


Overview:
This function returns the number of items to split/unpack from the current item.

Access variables:
current: the current object item: the involved object. This is the item that will be split/unpacked

Start of Experiment
Overview:
This function is executed once at the start of the experiment (before model reset).

Access variables:
replication: current replication number scenario: current scenario number

Start of Run (Start of Replication)


Overview:
This function is executed at the beginning of each replication run (after model reset).

Access variables:
replication: current replication number scenario: current scenario number

Start of Scenario
Overview:
This function is executed before the first replication of each new scenario (before model reset).

Access variables:
replication: current replication number scenario: current scenario number

Time Picklist (Inter-Arrivaltime Usage)


Overview:
Returns the number of seconds between creation of flowitems.

Access variables:
current: the current object For a list of pick options, see Time Picklists

Time Picklists
Note: The following picklist options are used in several pick lists, including Cycle Time, Setup Time, MTBF, MTTR, Load/Unload, and Time picklists. Some of the options below are not included in all of the above mentioned pick lists because the context was not appropriate. Note on distribution picklist options: Many of the pick options in these pick lists are distributions, and are not documented here. For more information on the different FlexSim distributions, refer to the ExpertFit documentation.

1. 2. 3. 4.

Load/Unload Time Setup Time Inter-arrival Time Cycle Time

Transport Dispatcher (Request Transport From)


Overview:
This function returns a reference to the dispatcher (or transport) that the transport request will be sent to. The return value needs to be cast into a number, since this function is hard-coded to return a double.

Access variables:
current: the current object item: the item to be transported

Triggers
1. 2. 3. 4. 5. 6. 7. 8. Load/Unload Trigger Entry/Exit Trigger Message Trigger Process Finish Trigger Creation Trigger OnDraw Trigger Reset Trigger OnResourceAvailable

Shared Tabs
1. 2. 3. 4. 5. 6. Connections Flow Visuals and General Properties Labels Object Triggers Statistics

Connections
Port Connections are used in a variety of ways in FlexSim Healthcare models, depending on the type of object. In the most general sense connections are just relationships that exist between various objects. These relationships tell objects to treat other objects in certain ways. For Patient and Item class objects, the connections facilitate the movements of patients and items from one object to another. For the Resource objects, such as staff groups, the connections tell the group to whom it may pass the requests it receives from Patient Track activities. Resource objects call this tab the tab, but the behavior of the interface is the same as connections shown below.

Connections: The Connections tab displays lists of objects in the model. The left column shows all available objects that could be connected to the current object, and the right will display any objects currently connected ot the current objects. The input connections buttons across the top toggle between the lists for objects that are either connected as inputs , or outputs the current object. Note: The input connection and output connection buttons shown above only appear on Item and Patient objects, not on resource objects. To add a connection, highlight the desired object on the left list, and click the right push button ( ) to send the object to the right list. To remove a connection, highlight the

desired object on the right list, and click the left push button ( ) to remove the object from the connections list. You may reorder connections in the right list by using the rank up ( ) buttons under the list.

Flow Tab Page

Output
These properties determine how the object sends flowitems downstream. Send To Port: This pick list returns the output port number connected to the object that the flowitem should be moved to. If 0 is returned, all outputs are opened and the flowitem is moved to the first downstream object that is able to receive it. See Send To Port pick list. Use Transport: If this box is checked, the object will request a transport to move the flowitem downstream. If it is not checked, the flowitem will be moved automatically. Priority: This parameter is only visible if "use transport" is checked. This value sets the priority of the task sequence that will be sent to the transporter or dispatcher. Transporters and dispatchers generally sort task sequences so that sequences with higher priorities will be performed first. Task sequences with the same priority will be performed in the order that they were received. Preempt: This parameter is only visible if "use transport" is checked. If this box is checked, the task sequences sent to the transporter will automatically preempt whatever the transporter is d oing at the time. This may cause the transporter to perform tasks that would normally not be allowed, such as carrying more flowitems than its capacity.

Request Transport From: This pick list is only visible if "use transport" is checked. This function returns a reference to the Dispatcher or Transporter that will be used to move the flowitem. See Transport Dispatcher pick list. Reevaluate Sendto on Downstream Availability: If checked, the Send To Port will be reevaluated every time a downstream object becomes available. It's important to note that this is only executed when the downstream object becomes available. It does not continuously evaluate just because a downstream object is already available. If you want to manually force a reevaluation at some other time than when a downstream object becomes available, then you can do so by calling the openoutput() command on this object.

Input
These properties define how an object pulls flowitems from upstream objects. Pull: If this box is checked, the object will pull flowitems from upstream objects. The upstream objects should open all their output ports to allow the object to pull the flowitems it needs. Pull from port: This parameter is only visible if "Pull" is checked. This pick list returns the input port number connected to the object that the next flowitem is to be pulled from. This field is evaluated only on reset of the model and when the pulling object becomes ready to receive its next flowitem. For a Processor with a capacity of 1, this means that the ?Pull From Port? field will only be evaluated once right after each flowitem exits the Processor. For a Conveyor, this field will be evaluated after a flowitem enters the conveyor and travels its product length. Opening and closing ports does not trigger this field to re-evaluate. See Pull Strategy pick list. Pull requirement: This parameter is only visible if "Pull" is checked. This pick list needs to return either a true or a false (1 or 0). This field is evaluated when considering whether or not to pull in a particular flowitem from the upstream object that was defined by the ?Pull from port? field. This field will only be evaluated for flowitems that are in the ?ready? state (i.e. FRSTATE_READY) meaning the flowitems are ready to leave the upstream object. Basically, the ?Pull Requirement? field is evaluated for every ?ready? flowitem immediately after the "Pull from port" field gets evaluated. The field is evaluated again for each new flowitem that later becomes ready in the upstream object. If the ?Continuously Evaluate Pull Requirement? box is checked, then when a new flowitem becomes ready, the ?Pull Requirement? will be reevaluated for all the ?ready? flowitems at that time, and in the order of their rank. See Pull Requirement pick list. Reevaluate Pull Requirement on All Items When Each Upstream Item is Released: This parameter is only visible if "Pull" is checked. If checked, the object will re-evaluate the pull requirement for all released flowitems upstream every time a new flow item is released. This is much like the Reevaluates Sendto on Downstream Availability check box, in that you may need to explicitly call openinput() if you want to manually trigger the re-evaluation of the pull requirement.

Visuals Tab Page


Item Objects:

Patient Objects:

Appearance
3D Shape: This option specifies the 3d shape for the object. Define a path to a .3ds, .wrl, .dxf, or .stl file. Edit 3D Shape Factors/Offsets: Click on this button to bring up a window that edits the object's 3D shape factors. 3d shape factors specify how the object's 3d shape is oriented with respect to the object.

The window above shows modified shape factors for a Queue's 3d shape. Notice that the yellow bounding box still reflects the true position and size of the queue, but the 3d shape has been offset in the x direction and scaled in the y direction.

2D Shape: This option specifies the 2d shape for the object, or a texture to be drawn at its base. Usually the 2D texture is not shown in the orthographic view, but is shown in the planar view. 3D Texture: This field specifies the object's 3d texture. If the 3D shape does not already have a texture defined within its 3d file, then this texture will be drawn on the face of the 3d shape. Note that if the object's 3d shape already has a texture defined, then this texture will not be used. Color: This field specifies the color of the object. Note that if the object already has materials defined in its 3d shape's file, then this color will not show. This color shows through only if no materials are defined in the 3d file.

Flags
Here you can check different boxes to show/hide different parts of the object, such as the contents of the object, the name, the ports, etc. Scale Contents: If this option is checked, any objects within the content of this object will be scaled according to the size of this object. This option is only available on Item Objects Protected: If this option is checked, this object will not allow the user to move, size, rotate, or delete the object.

Visuals/Animations
These buttons allow you to save/load visual information for objects. Load/Save: These buttons load/save all of the Appearance settings of an object, allowing you to save shape, texture, color, and animations in a .t file to load into other objects you want to look the same. Edit: This button opens the Animation Creator, which allows you to create animations for FlexSim Objects. See the Animation Creator page for more details.

Position, Rotation, and Size


Here you can set the position, rotation, and size of the object based on X, Y, and Z values.

Ports (Item Objects only)


This area lets you edit the object's connections. Select either Input Ports, Central Ports, or Output Ports from the combobox on the left. The list on the right shows the appropriate connections. Once you have finished editing an object's connections, you will need to reset the model before running it again. Rank ^: This button will move the selected connection up in the list. Rank v: This button will move the selected connection down in the list. Delete: This button will delete the selected connection. Properties: This button will open a new Properties window for the selected object.

Labels Tab Page


Labels are custom variables that you can specify on the object. For example, if you want to keep track of the number of flowitems of itemtype 3 that have entered an object, you can use a label to keep a record of this value. Use the commands setlabelnum(), getlabelnum(), and label() to interact with labels you have created. More information on these commands is found in the command summary.

The main panel shows a list of the labels on this object. Add Number Label: This option adds a new label with number data to the end of the list of labels. Add Text Label: This option adds a new label with string data to the end of the list of labels. Delete: This option deletes the selected labels. Duplicate: This option duplicates the selected labels.

Tree View
If you click the Tree View button, you can view and edit the list of labels in a tree. The window then has a splitter bar in the middle to change the size of each panel. You can click the Tree View button again to hide to tree view panel.

Label Table View


If you click the Label Table button, you can view and edit label tables within the same view. The window then has a splitter bar in the middle to change the size of each panel. The Label Table panel will be an additional table view of the selected label. You can click the Label Table button again to hide to Label Table panel. The commands used for editting tables can be used to edit label tables. The following example will set the value of the first cell in the label table "mylabeltable" to 8080 if current is a reference to this object.

settablenum(label(current,"mylabeltable"),1,1,8080);

Pop-up Menu
You can also edit labels by right clicking on a label. A pop-up menu will appear, giving you the options below. These options affect the label right-clicked on, not the entire selection.

Add Number Label: This option adds a number label to the object, the same as the

Add Number Label button at the bottom. Add Text Label: This option adds a text label to the object, the same as the Add Text Label button at the bottom. Delete Label: This option deletes the selected label. Duplicate Label: This option duplicates the selected label. Create/Edit Label Table: This option lets you use a label as a two-dimensional table. It brings up a table edit window to edit the label as a table. To get and set values in this table during the model run, you can use the gettablenum() and settablenum() commands, passing a reference to the label as the first parameter using the label() command. For more information on these commands, refer to the command summary. Example: gettablenum(label(current, "curitemtype"), 4, 5); Explore as Tree: This option lets you explore the selected label in a tree view.

Triggers Tab Page

Each object may have a different set of triggers. For more information about how triggers and pick lists work, refer to the Pick Lists page. OnArrival: This function is called on a Path when a traveler arrives at the node. If this function returns a non-zero value, then the traveler's next path to go to will be changed to the path specified by the return value. This return value is the rank of the next path, as shown in the Path's tab page. OnBreakDown: This function is called on an object when its Random Interrupt begins. OnContinue: This function is called on a Path when a traveler continues on to the next path leading out of the node. OnConveyEnd: This function is called on an Item Conveying when a flowitem reaches its end. See Process Finish Trigger pick list. OnCreation: This function is called on a Item Arrival when it creates a new flowitem. See Creation Trigger pick list. OnEndCollecting: This function is called on a Item Queuing when it has reached its batch limit. See Process Finish Trigger pick list. OnEntry: This function is called on an object when a flowitem is moved into it. See Entry/Exit Trigger pick list.

OnExit: This function is called on an object when a flowitem is moved out of it. See Entry/Exit Trigger pick list. Pickup: This function is called on an Operator or Transport when it completes loading a flowitem. See Load/Unload Trigger pick list. OnMessage: This function is called on an object when another object sends a message to it using the sendmessage() or senddelayedmessage() commands. See Message Trigger pick list. OnProcessFinish: This function is called on an object when its process time has expired. See Process Finish Trigger pick list. OnRepair: This function is called on an object when its Random Interrupt expires. OnResourceAvailable: This function is called when a downstream resource of a Group becomes available. OnSetupFinish: This function is called on an object when its setup time has expired. See Process Finish Trigger pick list. Dropoff: This function is called on an Operator or Transport when it completes unloading a flowitem. See Load/Unload Trigger pick list. Draw: This pick list allows you to define your own draw code for the object. If this field returns a 1, then the object's default draw code will not be drawn. Note that an object's draw code is different than its 3d shape being drawn. While most objects just show their 3d shape and don't have any draw code, some objects, like conveyors and racks, need more dynamic drawing capability, rather than a static 3d shape to draw. Returning 1 overrides this special drawing code, not the drawing of the object's 3d shape. To hide the 3d shape, un-check the show 3d shape box in the General tab page. Patient Message Received Trigger: This trigger is provided as a means to execute specialized behavior or custom code as a result of a patient receiving a message sent by some other object. See the command documentation for the sendmessage() and senddelayedmessage() commands for more information. Patient Entry Trigger: This trigger will fire whenever a patient enters any location within the model. These are separate from the OnEntry triggers provided on the patient Processing and Patient Queuing objects, as those triggers are valid for the individual objects only. This trigger is for the patients, wherever they may go. Patient Exit Trigger: Similar to the Patient Entry Trigger, this trigger fires for any patient that leaves any location in the model. Not to be confused with the locationcentric trigger OnExit. Activity Started Trigger: This trigger event fires after the activity is allowed to begin. For this trigger to happen, all conditions that govern the start of this activity must be true. This includes all predecessor activities to be completed, the Start Time

field, and the Activity Start Condition above. Activity Finished Trigger: This trigger fires after all tasks associated with this activity have completed, and activity specific results have been recorded. If the patient is in an exit, then the entire patient history will be saved; otherwise, a new activity to begin will be searched for, then variables for a repeating activity are reset.

Shared Tabs
1. 2. 3. 4. 5. 6. Connections Flow Visuals and General Properties Labels Object Triggers Statistics

Stats Tab Page

Throughput
Input: This box shows the number of items that have entered this object. Output: This box shows the number of items that have exited this object. Total Travel Distance (Patients/Staff only): This box shows the total distance traveled by this object.

State
Current: This box shows the object's current state value. Each state's meaning is dependent on the type of object involved. Refer to the library objects for more information about what each state means. Refer to the state list for a quick reference of each state's number and macro definition. Chart: This tab the object's state pie chart.

Patient Processing objects implement the following States:


STAT_OffSchedule: a state usually defined as unavailable time by Shift Schedules. STAT_Interrupted: a state usually defined as unavailable time by Random Interrupts. STAT_Occupied: the time the location has a patient in it, but is not blocked. STAT_Vacant: the time the location is empty (has no patient), but is not holding for a patient, and is not waiting for maintenance to finish. STAT_Blocked: the time from when the location has released its patient to when the patient actually leaves (does not apply when the room is being reserved). STAT_HoldingForPatient: the time from when the patient is released to go somewhere else to the time they reenter the location (only applies when the "Reserve Current Location" box for the transfer activity was checked). STAT_Maintenance: the time from when the patient exits the location to the time all maintenance tasks as defined on the Maintenance tab of the location's Properties window have completed. If a PatientProcessing location can accept more than one patient at a time, then these state definitions may not apply completely, because the state of the location will continue to be set by the latest event associated with different patients occurs.

Content
Current, Minimum, Maximum, Average: These boxes show the object's current, minimum, maximum, and average content values. The average content is weighted by time and not by the number of instances of a given content. Content History Size: This value limits the number of points stored in the content history.

Chart: This tab shows the object's content vs. time graph. Note: On the Content Graph, in order for an object's content graph to be recorded, the stats collecting of the object must be turned on for that object. You can turn on the stats collecting for this object using the "Record data for Content and Staytime charts" check box. You must reset and run the model after turning on stats collecting for the stats to be collected.

Staytime
Minimum, Maximum, Average: These boxes show the object's minimum, maximum, and average staytime values. Lower Bound: This value is the lower bound of the Y axis of the staytime histogram chart. Any values less than this value will be shown as Underflow in the chart. Upper Bound: This value is the upper bound of the Y axis of the staytime histogram chart. Any values greater than this value will be shown as Overflow in the chart. Divisions: This value is the number of divisions or "buckets" on the X axis of the staytime histogram chart. Display Confidence: This box allows you to display the confidence interval for the mean staytime. Interval %: This box allows you to edit the confidence interval for the mean staytime. Options for confidence percentage values are either 90, 95, or 99 percent confidence. Chart: This tab shows the object's staytime histogram. Note: In order for an object's staytime histogram to be recorded, the stats collecting of the object must be turned on for that object. You can turn on the stats collecting for this object using the "Record data for Content and Staytime charts" button. You must reset and run the

model after turning on stats collecting for the stats to be collected.

Task Sequences
1. 2. 3. 4. 5. 6. 7. Introduction Custom Built Task Sequences Querying Information on Task Sequences Task Sequence Preempting Coordinated Task Sequences Task Type Quick Reference Task Types

Coordinated Task Sequences


Coordinated task sequences are used for operations which require sophisticated coordination between two or more TaskExecuters. These task sequences implement concepts like allocation and de-allocation of TaskExecuters, as well as synchronizing several operations being done in parallel.

Example
A team of three operators share two forklifts. An operation needs one operator and one forklift. The operator should travel to the forklift, and the forklift should then move the operator into itself. Then the forklift should travel to the load location, pick an item, then travel to an unload location and drop off the item. Then the forklift should travel to its parking location, and unload the operator. Doing this using simple task sequences would be very difficult, because it deals with two different resources that work in a very coordinated fashion. Coordinated task sequences make this example much easier to simulate. The diagram below illustrates the two task sequences that need to be done for the forklift and operator. Notice that there are some parts where one resource needs to wait and do nothing while the other operates.

Commands
Coordinated task sequences are built and dispatched using a set of commands which are mutually exclusive from the default task sequence commands. The commands for coordinated task sequences are as follows. createcoordinatedtasksequence() insertallocatetask() insertdeallocatetask() insertsynctask() insertproxytask() dispatchcoordinatedtasksequence() For the previous example, the code to build the task sequence would be written as follows. It is assumed that references called operatorteam and forkliftteam have been established. These reference dispatchers to three Operator objects, and two Transporter objects, respectively. References have also been established for a loadstation from which to load, an unloadstation to unload to, and the item. treenode ts = createcoordinatedtasksequence(operatorteam); int opkey = insertallocatetask(ts, operatorteam, 0, 0); int forkliftkey = insertallocatetask(ts, forkliftteam, 0,0); int traveltask = insertproxytask(ts, opkey, TASKTYPE_TRAVEL, forkliftkey, NULL); insertsynctask(ts, traveltask); insertproxytask(ts, forkliftkey, TASKTYPE_MOVEOBJECT, opkey, forkliftkey); insertproxytask(ts, forkliftkey, TASKTYPE_TRAVEL, loadstation, NULL); insertproxytask(ts, forkliftkey, TASKTYPE_LOAD, item, loadstation); insertproxytask(ts, forkliftkey, TASKTYPE_TRAVEL, unloadstation, NULL); insertproxytask(ts, forkliftkey, TASKTYPE_UNLOAD, item, unloadstation); insertproxytask(ts, forkliftkey, TASKTYPE_TRAVEL, forkliftteam, NULL); insertproxytask(ts, forkliftkey, TASKTYPE_MOVEOBJECT, opkey, model()); insertdeallocatetask(ts, forkliftkey); insertdeallocatetaskyts, opkey); dispatchcoordinatedtasksequence(ts);

Note on the above example: There are some model maintenance issues involved here. For example, if you happen to stop and reset the model while the operator is inside of the forklift, you will need to move the operator out of the forklift and back into the model from a reset trigger. Also, whenever you move the operator back into the model, you will need to set its location appropriately, since it is transferring between two different coordinate spaces.

createcoordinatedtasksequence
The createcoordinatedtasksequence command takes one parameter, namely a reference to an object. This object is designated as the task coordinator who holds the task sequence, as well as coordinates the tasks. The task coordinator can also be one of the objects that is allocated within the task sequence. It can be any Dispatcher or TaskExecuter object. Note that selecting a task coordinator doesn't mean allocating that task coordinator. A task coordinator can be coordinating any number of coordinated task sequences at any one time. Also, unlike regular task sequences, coordinated task sequences are not queued up. The task coordinator will start executing the coordinated task sequence immediately when you dispatch it, no matter how many other coordinated task sequences it is coordinating.

insertallocatetask
The insertallocatetask command takes four parameters. The first is the task sequence. Second is the TaskExecuter or Dispatcher to give an allocated task to. When the task coordinator gets to an allocate task, it will actually create a separate task sequence with an allocated task in it, and pass that task sequence to the specified TaskExecuter or Dispatcher. In the case that it is a dispatcher, meaning you want to allocate any one of several TaskExecuters, then you can use the return value of this command as a key to reference the specific one that gets allocated, since you dont know exactly which one it is at the time that you build the task sequence. The third and fourth parameters are the priority and preempting values of the separate task sequence that will be created. The fifth parameter is optional, and specifies whether the task is blocking. By default (0), the task is blocking. If 1 is passed in, then the task will not be blocking.

insertproxytask
The insertproxytask command is similar to the inserttask command, with one parameter, the second, added. The second parameter specifies which allocated object you want to do the task. As the task coordinator is the one actually executing the task sequence, once he gets to a proxy task, he will instruct the allocated object to do the task by proxy. Notice that for involved1 and involved2, you can either pass in a key or a straight reference to an object.

insertsynctask
The insertsync task halts execution of the task sequence until a specified task, referenced by its key, is finished. It takes two parameters: the task sequence, and a key value of a given proxy task. It is important to note that proxy tasks which are specified for different TaskExecuters, by default, will be done in parallel, unless a sync task is specified, whereas proxy tasks given to the same TaskExecuter will automatically be done in sequential order, without the need for a sync task.

insertdeallocatetask
The insertdeallocatetask command de-allocates a specific TaskExecuter, referenced by its key. The first parameter references the coordinated task sequence. The second parameter is the allocation key for the resource you want to de-allocate. The third parameter is optional, and specifies whether the task is blocking. By default (0), the task is blocking. If 1 is passed in, then the task will not be blocking. The above code creates a coordinated task sequence that organizes the two task sequences, as shown in the diagram below. Coordinated Task Sequence

Things to Remember
The first thing you must do before giving any resource proxy tasks is to allocate that resource. You must get the key back from each allocate task, because you will use it later. The insertproxytask command takes a key for the executer of the proxy task. This is the key that the allocation task returns. You also will use this key when de-allocating the

object. While all proxy tasks for the same allocated resource are executed in sequence, proxy tasks for different allocated resources are executed in parallel, unless you explicitly put blocking tasks in the coordinated task sequence. Blocking tasks are ones that block the parallel execution of the coordinated task sequence. The task coordinator goes straight through the task sequence, giving proxy tasks to the appropriate allocated resources, until a blocking task is encountered. It will then wait until that task's blocking requirement is met before continuing the task sequence. In other words, execution of all tasks occurring after that blocking task (regardless of which resource they apply to) will be stopped until the blocking task's requirement is met . The blocking tasks and their blocking requirements are as follows. 1. Allocation Task: By default this task will block until the specified resource has been allocated. However, if the fifth parameter of insertallocatetask is 1, then the allocate task will not block. 2. Sync Task: This task will block until the proxy task specified by its key is finished. 3. De-allocation Task: By default this task will block until the specified resource has finished all its proxy tasks and is deallocated. However, if the third parameter of insertdeallocatetask is 1, then the de-allocate task will not block. The order in which you insert your tasks can have subtle yet important implications. This is especially true for placing your proxy tasks in relation to blocking tasks. Proxy tasks placed after certain blocking tasks can be executed very differently than if those proxy tasks were inserted before the blocking tasks. Make sure that you de-allocate all objects that you allocate, or the task sequence won't properly release the objects it has allocated. Once you have de-allocated a resource, do not give it any more proxy tasks.Note on non-blocking de-allocate and allocate tasks: The functionality for allowing these tasks to be non-blocking is still in the beta state. Although we encourage you to use this feature, and there are no known bugs at the time of writing, know that you may run into some problems because this functionality hasn't yet been used extensively.

Custom Built Task Sequences


You can also create custom task sequences using 3 simple commands: createemptytasksequence() inserttask() dispatchtasksequence() First, create a task sequence by using createemptytasksequence(). Then insert tasks into the task sequence by successive inserttask() commands. Finally dispatch the task sequence with dispatchtasksequence(). The following example tells a forklift to travel to an object, referenced as "station", then load a flow item, referenced as "item." treenode newtasksequence = createemptytasksequence(forklift, 0 ,0 ); inserttask(newtasksequence, TASKTYPE_TRAVEL, station); inserttask(newtasksequence, TASKTYPE_LOAD, item, station, 2); dispatchtasksequence(newtasksequence); If you are confused by the "treenode" syntax, refer the help on the FlexSim tree structure. In brief terms, "treenode newtasksequence" creates a reference, or pointer, to the task sequence as a FlexSim node so that it can be used later when tasks are added to the task sequence. The createemptytasksequence command takes three parameters. The first parameter is the object that will handle the task sequence. This should be a Dispatcher or TaskExecuter object. The second and third parameters are numbers, and specify the task sequence's priority and preempting values, respectively. The command returns a reference to the task sequence that was created. The inserttask command inserts a task onto the end of the task sequence. Each task that you insert has several values associated with it. First, it has a type value, which defines what type of task it is. It also has a reference to two involved objects for the task, referred to as involved1 and involved2. These involved objects and what they mean depend upon the task type. For some task types both involved parameters are needed and have meaning, whereas for others, the involved objects are not used. Some task types may use one involved object, and some have involved objects which are optional. Refer to the documentation on task types for information on what a specific task type's involved objects represent. The task can also have up to four number values. These are task variables, referred to as var1, var2, var3, and var4. Again, their meaning depends on the task type. For the load task below, notice that var1 was specified as 1. For a load task, this specifies the output port through which

the item will leave the station.

The inserttask command takes two or more parameters, which specify the task's values. The first parameter is a reference to the task sequence into which the task is inserted. The second is the type of task. This can be chosen from an enumerated list of task types. The third and fourth parameters reference the two involved objects. If a specific involved object is not used or is optional for a task type, then you can simply pass NULL into the inserttask command, or even leave that parameter out if there are no number variables that you need to specify either. The fifth through ninth parameters are optional, and define var1-var4. By default, these values are zero. Note on optional parameters: Even though many of the parameters of the inserttask command are technically optional, depending on the task type, you will still need to specify them. Also, parameters need to still be specified in their correct order. If, for example, you want to specify var1 of the task, but don't care what involved1 or involved2 are, you will still need to pass the NULL value into parameters 3 and 4, even though they are optional, in order to correctly pass var1 in as parameter 5.

Building a Basic Custom Task Sequence Part 1


Introduction
In this tutorial, you will learn how to build a basic task sequence from scratch. The operator will pick up the flowitem from a Queue, take it to a table to inspect the item, then take the item to a Processor. Writing your own task sequence will allow you to allocate and use one Operator for the entire task. This tutorial assumes a solid knowledge of basic interaction with the software, and will ask you to write several lines of code. If at any time you encounter difficulties while building this model, a fully functional tutorial model can be found at http://www.FlexSim.com/tutorials For more on Tasktypes and their parameters, see the Task Types page.

Step 1: Setup the model


Create a Source, a Queue, a BasicFR, a Processor, a Queue, a Processor, an Operator and a Sink, and lay them out as shown in the picture below. The BasicFR will act as our table, but will not have any logic applied to it, and will not function in any way. It is just there to give the Operator somewhere to travel to. A Visual Tool could have also been used, or any of the Fixed Resources. Connect the objects as shown in the picture below, making sure to connect the Operator and the BasicFR to the center port of the first Queue in that order.

Step 2: Edit the Objects


Double-click on the first Processor to open its Properties window. On the Processor tab, change Maximum Content to 10. Click OK to close the Properties window.

Double-click on the second Processor to open its Properties window. On the Processor tab, change the Process Time to 50. Click OK to close the Properties window.

Step 3: Write the Task Sequence


To make things easy, you will use the Basic Task Sequence Example to start the task sequence. From there, you will alter and add to it to fit your needs. Double-click the first Queue to open its Properties window, then click the Flow tab. On the Flow tab, check the Use Transport box, and select Task Sequence Example_1 from the list. This task sequence example by default provides the same functionality as referencing an operator. The Operator travels to the current object, loads the item, travels to the downstream object, and unloads the item. You will alter this just a little bit.

To the right of the Request Transport From list click the Code Edit button to open the code editor. In this model, the Operator should do this task, and nothing else. So, you will remove the Break task by deleting all of the code on line 14. See the image below.

After the Operator loads the item, we want him to Travel to the BasicFR, and Delay for 10 seconds before traveling to the downstream Processor. On the now empty line 14, type the following: inserttask(ts, TASKTYPE_TRAVEL, centerobject(current,2), NULL); Press the Enter key to go to the next line.

On line 15, type the following: inserttask(ts, TASKTYPE_DELAY, NULL, NULL, 10, STATE_BUSY); Click the OK button to close the code window.

Click the OK button on the Properties window to close it.

Step 4: Reset and Run the Model


Reset and Run the model. The Operator should Travel to the Queue, Load the item, Travel to the BasicFR, Delay for 10 seconds, Travel to the Processor, and Unload the item. Save the model. The next tutorial will build off of what you have done here.

Building a Basic Custom Task Sequence Part 2


Introduction
In this tutorial, you will build off the model you completed in Custom Task Sequence Tutorial 1. The Operator will now stay at the Processor to process the item before he starts the next task sequence. This tutorial assumes a solid knowledge of basic interaction with the software, and will ask you to write several lines of code. If at any time you encounter difficulties while building this model, a fully functional tutorial model can be found at http://www.FlexSim.com/tutorials For more on Tasktypes and their parameters, see the Task Types page.

Step 1: Load the Model


If you have not already done so, load the model from Task Sequence Tutorial 1.

Step 2: Add the Utilize Task


Double-click on the first Queue to open its Properties window, and click the Flow tab. click the Code Edit button to the right of the Use Transport list to open the code editor.

Add a new line after Line 17. On line 18, type the following: inserttask(ts, TASKTYPE_UTILIZE, item, outobject(current, 1), STATE_UTILIZE);

Click OK to close the Code Edit window. If your Run the model now, you will notice that the operator stays at the Processor forever after the item has been unloaded and processed. This is because nothing is freeing the Operator, and the Operator will stay utilized until it is freed by an object. The best place to do this is in the OnProcessFinish of the Processor that is utilizing the Operator.

Step 3: Edit the Processor to Free the Operator


Connect the Operator to the first Processor with a center port connection.

Double-click the first Processor to open its Properties window, then click the Triggers tab. In the OnProcessFinish trigger list, select Free Operators. The default trigger parameters will work for this model. The Involved is the first parameter in the TASKTYPE_UTILIZE command we used in the previous step. In order for the Operator to be freed, the involved object must match, in this case, item.

Click the OK button on the Properties window to close it.

Step 4: Reset and Run the Model


Reset and Run the model. The Operator should Travel to the Queue, Load the item, Travel to the BasicFR, Delay for 10 seconds, Travel to the Processor, Unload the item, and stay at the Processor for the Process Time. Save the model. The next tutorial will build off of what you have done here.

Building a Basic Custom Task Sequence Part 3


Introduction
In this tutorial, you will build off the model you completed in Custom Task Sequence Tutorial 2. The Operator will now pick the item up from the Processor, and carry it to the second Queue. This tutorial assumes a solid knowledge of basic interaction with the software, and will ask you to write several lines of code. If at any time you encounter difficulties while building this model, a fully functional tutorial model can be found at http://www.FlexSim.com/tutorials For more on Tasktypes and their parameters, see the Task Types page.

Step 1: Load the Model


If you have not already done so, load the model from Task Sequence Tutorial 2.

Step 2: Delete the OnProcessFinish Trigger


Since you will be adding to the task sequence, a change needs to be made in how the Operator is released from the Utilize task. The freeoperator() command needs to be moved to the Request Transport From field in order for the model to work correctly. If you need more information, an in-depth explanation will be provided at the end of the tutorial. Double-click on the first Processor to open its Properties window, and click the Triggers tab. In the OnProcessFinish trigger, click the on this trigger. Don't close the Properties window yet. button, and then click the button to remove the function

Step 3: Write the Flow Logic


Now you will need to free the operator in the Request Transport From field. Also, since the next set of tasks you will add will override the Processor's flow logic, specifically the Request Transport From logic, you need to tell the processor that it doesn't need to create a task sequence. Note: Whenever you write a task sequence that controls the output of an object somewhere other than the Request Transport From on the object the task sequence is affecting, you MUST return 0 in that object's Request Transport From logic, otherwise there will be serious problems. In this example, you are writing the task sequence on the Queue, but the next tasks you will add affect the Processors natural transport logic, so even though the task sequence is on the Queue, you will need to return 0 on the Processor's Request Transport From logic. You would also need to do this if you were writing a task sequence in a trigger field instead of in the Request Transport From. Double-click on the first Processor to open its Properties window, and click the Flow tab. Check the Use Transport box, then choose Free Operators from the drop down list. The default parameters should work fine for this model. Notice that the description points out that this option returns 0 for you, so you don't have to worry about writing this anywhere.

Click the OK button to close the Properties window.

Step 3: Write the rest of the Task Sequence


Double-click the first Queue to open its Properties window, click the Flow tab, then click the Code Edit button to the right of the Use Transport list.

You will need to create a local variable so that you can more easily reference the second Queue in you task sequence. On line 9, type the following:

treenode downQueue = outobject(outobject(current, 1), 1);

Starting on line 19, type the following: inserttask(ts, TASKTYPE_FRLOAD, item, outobject(current, 1)); inserttask(ts, TASKTYPE_TRAVEL, downQueue, NULL); inserttask(ts, TASKTYPE_FRUNLOAD, item, downQueue, 1);

Click the OK button on the Code Window and the Properties window to close them. Note: The reason that the freeoperators() command needed to be changed from the OnProcessFinish is due to the fact that a written task sequence has the ability to override the internal logic of objects. If the downstream queue isn't available when the Processor finishes its process time, then the Processor will release the Operator to load/unload the part into the Queue before it's actually available, which can cause the Queue to be over-filled, and can cause some other problems. So by moving the freeoperators() to the Request Transport From field, the operator will only be freed to continue with the load/unload only when the downstream queue is ready to receive that part. The perfect solution to this problem would be to have two utilize tasks, freeing the Operator on both the OnProcessFinish, and the Request Transport From. This way, the operator would be free after the Processor finishes, in case you need him to break, but he won't move the item until the downstream object is available.

Step 4: Reset and Run the Model


Reset and Run the model. The Operator should Travel to the Queue, Load the item, Travel to the BasicFR, Delay for 10 seconds, Travel to the Processor, Unload the item, stay at the Processor for the Process Time, Load the item, Travel to the next Queue, and Unload the item. Save the model.

Querying Information on Task Sequences


Once you have dispatched task sequences, you can also query and change certain values on those task sequences. The following commands allow you to make such queries and changes.

treenode gettasksequencequeue(treenode dispatcher)


This command returns a reference to the task sequence queue of a dispatcher/taskexecuter object. It can be treated like a regular treenode. Say, for example, I am a dispatcher, and I want to query things on the first task sequence in my queue. I could access the task sequence by:

first(gettasksequencequeue(current)) treenode gettasksequence(treenode dispatcher, int rank)


This command is another way that you can get references to task sequences. Rank is the rank of the task sequence in the task sequence queue. Also, if rank = 0, then it will return a reference to the currently active task sequence for the task executer, or the task sequence that he is doing right now.

treenode gettaskinvolved(treenode tasksequence, int rank, int involvednum)


This command returns a reference to an involved object for a given task in a task sequence. Rank is the rank of the task in the task sequence. Involvednum is a 1 or a 2, and references which involved object. Say, for example, that a TaskExecuter is about to do a load task, but he wants to know the object from whom he is loading the item. In a load task, involved1 is the item, and involved2 is the station from which to load. Let's say also that I know that the load task is the 3rd task in the sequence, and the task sequence is currently the active task sequence to get a reference to the station, I would code:

gettaskinvolved(gettasksequence(current,0), 3, 2)
You'll need to know task types and which involved means what for a given task type, but once you know that, it's easy. Most of it is documented in the begintask() method of the TaskExecuter in the library.

int gettasktype(treenode tasksequence, int rank)


This command returns the task type of a given task. Rank is the rank in the task sequence. You can compare this with macros like TASKTYPE_LOAD, TASKTYPE_TRAVEL...

int getnroftasks(treenode tasksequence)


Returns the number of tasks in the task sequence that have not yet been finished.

int gettotalnroftasks(treenode tasksequence)


Returns the total number of tasks in the task sequence.

int gettaskvariable(treenode tasksequence, int rank, int varnum)


Returns the value of a variable in the task of a tasksequence. Again, rank is the rank of the task in the task sequence. Varnum is a number between 1 and 4, and is the variable number. As in the involved objects, variable numbers and what they mean depend on the task type.

int getpriority(treenode tasksequence)


Returns the priority of a given task sequence.

void setpriority(treenode tasksequence, double newpriority)


Sets the priority of the tasksequence

int getpreempt(treenode tasksequence)


Returns the preempt value for the task sequence. You can compare this with PREEMPT_NOT , PREEMPT_ONLY, PREEMPT_AND_ABORT_ACTIVE, PREEMPT_AND_ABORT_ALL. For information on preempting, go to Task Sequence Preempting.

void setpreempt(treenode tasksequence, int newpreempt)


Sets the preempt value of a task sequence. You would pass into newpreempt one of the previously mentioned macros. For information on preempting, go to Task Sequence Preempting.

Task Sequence Preempting


Every task sequence has a preempting value. Preempting is used to break a TaskExecuter away from its current operation to execute a more important operation. For example, operator A's most important responsibility is to repair machines. When there are no machines to repair, however, it should also transport material throughout the model. If a machine breaks down while operator A is in the middle of transporting a flowitem somewhere, then the operator should stop whatever he is doing and repair the machine, instead of finishing the transport operation. To do this, you will need to use a preempting task sequence to break the operator away from his current operation. To create a preempting task sequence, specify a non-zero value in the preempt parameter of the createemptytasksequence() command. createemptytasksequence(operator, 0, PREEMPT_ONLY); There are four possible preempt values. These values tell the TaskExecuter what to do with the original task sequence(s) that have been preempted. 0 - PREEMPT_NOT - This value is non-preempting. 1 - PREEMPT_ONLY - If a task sequence has this value, then the TaskExecuter will preempt the currently active task sequence and put it back in its task sequence queue to be finished later. When a task sequence is preempted, it is automatically placed at the front of the task sequence queue. When the TaskExecuter eventually comes back to the original task sequence, the current task in that task sequence will be done over again, since it was not finished. Also, you can specify a series of tasks to do over again when it comes back to the task sequence using the TASKTYPE_MILESTONE task. This preempt value is the most common used. 2 - PREEMPT_AND_ABORT_ACTIVE - If a task sequence has the PREEMPT_AND_ABORT_ACTIVE value, then the TaskExecuter will stop the currently active task sequence and destroy it, so that it will never come back to that original task seqeunce. 3 - PREEMPT_AND_ABORT_ALL - If a task sequence has the PREEMPT_AND_ABORT_ALL value, then the TaskExecuter will stop the currently active task sequence, destroy it, and destroy all task sequences in its task sequence queue. To query or change the preempting and/or priority values of a task sequence, you can use the getpreempt(), setpreempt(), getpriority(), and setpriority() commands. For more information on these commands, refer to the "Commands" documentation found through FlexSim's Help menu.

Interaction Between Multiple Preempting Task Sequences

If a TaskExecuter is currently working on a preempting task sequence, and it receives a new task sequence that is also preempting, it will use the priority value of the task sequence to determine which task sequence to do. If the priority value of the new task sequence is higher than the priority value of the one it is currently working on, the TaskExecuter will preempt its current task sequence and execute the new one. If the priority value of the new task sequence is less than or equal to the priority of the task sequence it is currently working on, then the TaskExecuter will not preempt the active task sequence, but will queue up the new task sequence just like any other task sequence it receives. If it must queue up the task sequence, it will not take the preempt value into account for its queueing logic unless you explicitly tell it to in the queue strategy. Note on queueing a preempting task sequence: If a preempting task sequence does not actually preempt a TaskExecuter, then it will be queued up like any other task sequence. If you want to have preempting task sequence be brought to the front of the queue, then either make your preempting task sequences have higher priority than all other task sequences, or take preempting into account in the queue strategy.

Preempting With Dispatchers/Groups


If a preempting task sequence is given to a Group, the Dispatcher will consider the preempt value of the task sequence As well as whatever other criteria exist in the Member Selection Policy. See the options available in the Group's Memember Selection Polict for additional information

Task Type Quick Reference


Task Type
TASKTYPE_TRAVEL TASKTYPE_LOAD TASKTYPE_FRLOAD TASKTYPE_UNLOAD TASKTYPE_FRUNLOAD TASKTYPE_UTILIZE TASKTYPE_DELAY TASKTYPE_BREAK TASKTYPE_CALLSUBTASKS

involved1
destination item to load item to load item to unload item to unload involved NULL

involved2
NULL station station station station station NULL

var1
end speed output port output port input port input port state time

var2
forcetravel end speed end speed end speed end speed

var3

var4

state check receive pv(4)* msgp(2)** repeat id msgp(2)** y y y y pv(5)* msgp(3)** pv(5)* msgp(3)** id already executed msgp(3)** z z z z delay time end speed end speed end speed end speed pv(6)* pv(6)* priority

send message check task sequence to content send message pv(3)* task sequence to msgp(1)** NULL NULL from object NULL NULL station station container state repeat msgp(1)** x x x x output port

TASKTYPE_STOPREQUESTBEGIN object to stop TASKTYPE_STOPREQUESTFINISH TASKTYPE_SENDMESSAGE TASKTYPE_TRAVELTOLOC TASKTYPE_TRAVELRELATIVE TASKTYPE_PICKOFFSET TASKTYPE_PLACEOFFSET TASKTYPE_MOVEOBJECT object to resume to object NULL NULL item item object to move object to destroy node to set user-defined NULL node object object object

TASKTYPE_DESTROYOBJECT TASKTYPE_SETNODENUM TASKTYPE_TAG TASKTYPE_MILESTONE TASKTYPE_NODEFUNCTION TASKTYPE_STARTANIMATION TASKTYPE_STOPANIMATION TASKTYPE_FREEOPERATORS

NULL NULL user-defined NULL parnode(1) NULL NULL involved value userdefined range pv(2)* increment y/n user-defined user-defined N/A pv(3)* N/A pv(4)* userdefined N/A pv(5)*

animationnr durationtype durationvalue animationnr

Non-user tasks
TASKTYPE_TE_STOP TASKTYPE_TE_RETURN TASKTYPE_TE_ALLOCATED NULL NULL state

task sequence task coordinator task sequence

TASKTYPE_CT_ALLOCATE

dispatcher

allocated object NULL NULL

priority key or task rank key or task rank

preempt

front-most proxy task

blocking, (0)yes, (1)no

TASKTYPE_CT_SYNC TASKTYPE_CT_DEALLOCATE * pv = parval ** msgp = msgparam

NULL NULL

blocking, (0)yes,(1)no

Task Types
You can also refer to the task type quick reference guide. Task types are as follows.

TASKTYPE_TRAVEL
Here the TaskExecuter travels to the object specified. This is done by making a travel request to the navigator that it is connected to. The navigator then takes over control of the TaskExecuter, and pushes it like a pawn on a chessboard, according to the navigator's own logic, until the TaskExecuter reaches the destination and the navigator notifies the TaskExecuter that the travel task is finished. How the TaskExecuter is pushed is dependent on the type of navigator. If the TaskExecuter is connected to a network, then its associated navigator is a network navigator and will push the TaskExecuter along network paths. Note on TaskExecuters and navigators: Some objects by default are not connected to a navigator at all. If the TaskExecuter is not connected to a navigator, then it will do nothing for the travel task. The following objects do not connect to any navigators by default: ASRSvehicle, Elevator, Robot, Crane. involved1 The object to travel to. involved2 Not used. Use NULL for this parameter.

var1

This specifies the desired end speed for the travel operation. If 0, then the desired end speed will be the maximum speed of the TaskExecuter. If -1, then the desired end speed will be 0. Otherwise, the desired end speed will be the value itself. If this value is 1, then the object will travel to the destination node even he is already connected to it. N/A

var2 var3 var4

Example

inserttask(ts, TASKTYPE_TRAVEL, outobject(current,1))

TASKTYPE_LOAD, TASKTYPE_FRLOAD
This task causes the TaskExecuter to load an item from a station. If the TaskExecuter's "Travel Offsets for Load/Unload Tasks" checkbox is checked in its Properties page, then it will travel to the location of the given flow item by querying the location from the station and using offset travel. Then the TaskExecuter will figure out the load time. At the end of the load time, the TaskExecuter will move the item into itself. For Frload, it will notify the FixedResource right before it moves the item, so that the FixedResource can update its own tracking data. involved1 the object to load (usually a flow item). involved2 var1 var2 var3 var4 the object to load from (FixedResource is assumed if the tasktype is specified as FRLOAD). this is the output port through which the object will exit the station. Usually a 0 is fine. The requested end speed for the task. N/A

Example

inserttask(ts, TASKTYPE_LOAD, item, current) inserttask(ts, TASKTYPE_FRLOAD, item, current)

TASKTYPE_UNLOAD, TASKTYPE_FRUNLOAD
This task causes the TaskExecuter to unload an item to a station. If the TaskExecuter's "Travel Offsets for Load/Unload Tasks" checkbox is checked in its Properties page, then it will travel to a drop-off location by querying the station and using offset travel. Then the TaskExecuter will figure out the unload time. At the end of the unload time, the TaskExecuter will move the item into the station. For Frload, it will notify the FixedResource right before it moves the item, so that the FixedResource can update its own tracking data. involved1 the object to unload (usually a flow item). involved2 the object to unload to (FixedResource is assumed if the tasktype is specified as FRLOAD). this is the input port through which the object will enter the station. Usually a 0 is fine, unless you are unloading to a Combiner, which needs to know the input port an item enters through in order to update its input table. The requested end speed for the task. N/A

var1 var2 var3 var4

Example

inserttask(ts, TASKTYPE_UNLOAD, item, outobject(current, 1)) inserttask(ts, TASKTYPE_FRUNLOAD, item, outobject(current, 1))

TASKTYPE_BREAK
This task causes the TaskExecuter to "break" from its currently active task sequence to a new task sequence as the diagram below illustrates.

The involved objects and variables allow you to customize how to find the task sequence to break to. In the default case, the TaskExecuter will call its "Break To Requirement" function.

This function should return a reference to the task sequence that you want the TaskExecuter to break to. In your break logic you may search through the TaskExecuter's task sequence queue by using task sequence query commands, or you can create the task sequence explicitly using createemptytasksequence. If you don't want the TaskExecuter to break at all, then return NULL.

If involved1 is specified, then it should be a reference to some object in the model. Instead of calling the "Break To Requirement" the TaskExecuter will send a message to this object. The only difference here is the place in which you place your logic for finding a task sequence to break to. By default, the logic executes in the Break To Requirement, but if this parameter is specified, then you will write your logic in a message trigger. Again, the return value of the message should be a reference to the task sequence. You would most likely use this feature if you involved1 want to centralize your logic through messages to a central "Model Control Center." Note on the return value: In the message you will need to cast the reference to the task sequence into a number, because message triggers return a number type. You can do this by using the tonum() command: tonum(mytasksequence) If involved2 is specified, then it is interpreted as a straight reference to the task sequence that the TaskExecuter should break to. This would only be used if you know exactly which task sequence you want to break to at the time that you create the task sequence with the break in it. This parameter is not used very often, because if you know exactly which task sequence to break to when you create a task sequence, then you can just add the tasks into the original task sequence when you create it. Note on using both involved parameters: If the involved1 parameter of this task is specified, then involved2 should be NULL. Likewise, if involved2 is specified, then involved1 should be NULL. These parameters are mutually exclusive. You can also just use the default case by specifying both of the involved parameters as NULL.

involved2

This parameter specifies whether or not the content of the TaskExecuter should be screened before performing the break task. By default (0), the TaskExecuter will only perform a break task if its current content is less than the maximum content

var1

specified in its Properties page. If var1 is not 0, however, then the TaskExecuter will ignore its current content, and perform the break task anyway. This parameter is also passed in as parval(3) if it is to call its Break To Requirement function, and as msgparam(1) if it is to send a message. This parameter specifies whether or not the TaskExecuter should check to receive task sequences from an upstream Dispatcher. By default (0), the TaskExecuter will see if it has any task sequences in its queue. If the queue is empty, or if all of the task sequences in its queue are task sequences that have already been started and broken out of, then it will open its input ports and receive a task sequence from an upstream dispatcher. However, if var2 is not zero, then the TaskExecuter will not receive anything from an upstream dispatcher before calling its break logic. This parameter is also passed in as parval(4) if it is to call its Break To Requirement function, and as msgparam(2) if it is to send a message. These parameters are passed into the Break To Requirement as parval(5) and parval(6), and var 3 is passed into the message as msgparam(3) if the task is to send a message.

var2

var3 var4

Example

inserttask(ts, TASKTYPE_BREAK, NULL, NULL) //a basic break. the "Break To" Requirement on the TaskExecuter tab will fire inserttask(ts, TASKTYPE_BREAK, centerobect(current, 1), NULL) //Sends a message to the referenced object, where your logic will be written in the OnMessage trigger of the object inserttask(ts, TASKTYPE_BREAK, NULL, specificTaskSequence) //breaks to a specified task sequence

TASKTYPE_CALLSUBTASKS
This task is just like the break task, except that it ensures that as soon as the second task sequence is finished, it will return immediately to the next task of the original task sequence. The following illustration shows how this works.

As the diagram shows, Task Sequence A comes to a call sub tasks type, upon which it breaks to Task Sequence B. Immediately after Task Sequence B is finished, it returns to the next task of Task Sequence A. Often Task Sequence B won't be created until Task Sequence A actually

gets to the call sub tasks task. This is because often when you create Task Sequence A, you don't know exactly what you want the TaskExecuter to do when he gets to the point of the call sub tasks task, or you don't have an up-front reference to the objects you need. For example, what if you want the TaskExecuter to travel to one part of the model, then load an item, then travel to another part of the model and unload the item, but you don't have a reference to the item that you want to load. You want the TaskExecuter to travel to that portion of the model, then figure out which item to load. Here you would use call sub tasks so that you can resolve the reference to the item at the time the TaskExecuter arrives at the load location. Call sub tasks can also be heirarchical. This means that Task Sequence B can also have a call sub tasks type in it. If you decide to create the task sequence when the TaskExecuter gets to the call sub tasks task, then you will need to create the task sequence using createemptytasksequence(), and insert tasks using inserttask(), but do not dispatch the task sequence using dispatchtasksequence(). Simply return the reference to the task sequence. Note on the Break To Requirement function: When the TaskExecuter comes to this task type, by default, he will call his "Break To Requirement" function. He will pass in a 1 as parval(2), so that within the function you can tell that it is a call sub tasks instead of the usual break task. Note on Coordinated Task Sequences: Using the diagram above, if Task Sequence B is a coordinated task sequence, then the TaskExecuter that executes the call sub tasks task from Task Sequence A must be the first object to be allocated in the Task Sequence B.

If involved1 is specified, then it should be a reference to some object in the model. Instead of calling the "Break To Requirement" the TaskExecuter will do one of two things. If involved1 is a reference to an object (a node with object data) then the TaskExecuter will send a message from itself to the object specified by the involved1 parameter. If involved1 is a reference to a dll, flexscript, or c++ node (a node with string data) then it will call nodefunction on that node, and it will pass a reference to itself as parnode(1). The only difference here vs. the default case is the place in which you put your logic for finding a task sequence to break to. By default, the logic executes in the Break To Requirement, but if this involved1 parameter is specified, then you will write your logic in a message trigger or nodefunction. Again, the return value of the message/nodefunction should be a reference to the task sequence. You would most likely use this feature if you want to centralize your logic through messages to a central "Model Control Center." Note on the return value: In the message you will need to cast the reference to the task sequence into a number, because a message trigger returns a number type. You can do this by using the tonum() command: tonum(mytasksequence) If involved2 is specified, then it is interpreted as a straight reference to the task

sequence that the TaskExecuter should break to. This would only be used if you know exactly which task sequence you want to break to at the time that you create the task sequence with the break in it. This parameter is not used very often, because if you know exactly which task sequence to break to when you create the original task sequence, then you should just add the tasks into the task sequence when you create it. It does, however, allow you to specify different priority and preempting values for different portions of your task sequence, so that if you don't involved2 want a certain portion of your task sequence to be preempted, then you can have that portion be a sub-routine task sequence with a different priority than the original task sequence. Note on using both involved parameters: If the involved1 parameter of this task is specified, then involved2 should be NULL. Likewise, if involved2 is specified, then involved1 should be NULL. These parameters are mutually exclusive. You can also just use the default case by specifying both of the involved parameters as NULL. These parameters are passed into the Break To Requirement as parval(3), parval(4), parval(5) and parval(6). When sending a message, var1, var2, and var3 are passed into the message as msgparam(1),msgparam(2) and msgparam(3) respectively. When calling a nodefunction, var1, var2, var3 and var4 are passed in as parval(2), parval(3), parval(4), and parval(5).

var1 var4

Example

inserttask(ts, TASKTYPE_CALLSUBTASKS, NULL, NULL) // The "Break To" Requirement on the TaskExecuter tab will fire inserttask(ts, TASKTYPE_CALLSUBTASKS, centerobect(current, 1), NULL) // Sends a message to the referenced object, where your logic will be written in the OnMessage trigger of the object inserttask(ts, TASKTYPE_CALLSUBTASKS, NULL, specificTaskSequence) // breaks to a specified task sequence

TASKTYPE_UTILIZE
This task causes the TaskExecuter to go into a given state, and then wait until it is freed from that state with the freeoperators() command. This task is used frequently when you want an operator to "do something" at a station, but at the time you create the task sequence you don't know how long it will take to finish whatever the operator is doing. In such a case, use this task type to cause the operator to go into the state you specify, and then free him when he is finished, using the freeoperators() command. This can be done from a trigger like OnProcessFinish or OnSetupFinish, etc. If you know from the outset how long the operator will have to be "doing something", then you can use the delay task instead. Often this parameter will be a reference to a flow item, if the operator's job has to do with processing a flow item. Sometimes it references a station,

for example in the case that a station goes down, and an operator is called. Here, the operator is working on the station, and not a flow item, so the station would be the involved1 parameter. You can even specify this parameter to be NULL if you like. In more specific terms, this parameter is a key for matching with the freeoperators command. For example, if this parameter is a flowitem, then when the freeoperators command is called, the same flowitem must be passed into the second parameter of the freeoperators command in order for the operator to be freed properly. Often involved1 you will use a team of operators, any one of which can do the job you want. In such a case you would give the task sequence to a dispatcher, and the dispatcher would give it to a member of the team. At the time you call freeoperators, you really don't know exactly which operator finally came and worked on your job, so you send the freeoperators command to the dispatcher, and in the freeoperators command, you make the second parameter match the involved1 parameter that you specified for this task. This allows the dispatcher to basically say to his team, "Any of you who are doing a Utilize task whose involved1 parameter is this can now finish that task". This makes it so that the dispatcher can free certain operators from the right tasks without freeing other operators from the wrong tasks. This parameter only needs to be specified if it is possible for the operator to be preempted away from his operation. An operator can be preempted away from an operation by a preempting task sequence, or by a stopobject() command, or by a global TimeTable or global MTBF table. If the operator is preempted away from a utilize task, then problems can be caused if the freeoperators command is called before he comes back to the utilize task. If freeoperators is called while he is doing something else, then the operator will simply ignore it, thinking it doesn't apply to him. Then, once he comes back to the operation, he will never be freed because the involved2 modeling logic thinks that he's already been freed. This involved2 parameter can be used to help alleviate this problem. If involved2 is specified, then it should point to an object in the model that is responsible for freeing the operator. When the operator is preempted, he will call stopobject() on the specified object, which stop the object, and in most cases thus stop the object from calling freeoperators. Once the operator comes back to the utilize task, he will call resumeobject() on the station, and things will resume as normal, and the operator will eventually be freed. If you would like to know more about preempting, refer to its corresponding help section. var1 var2 var4 This is the state into which the operator will go during the utilize task. If it is 0, then the TaskExecuter will go into STATE_UTILIZE. N/A

Example

inserttask(ts, TASKTYPE_UTILIZE, item, NULL, STATE_UTILIZE)

TASKTYPE_STOPREQUESTBEGIN
This task causes the TaskExecuter to call stopobject() on the involved1 object. Refer to the stopobject() command documentation for more information. involved1 This parameter specifies the object to call stopobject() on. If NULL, then the TaskExecuter will call stopobject on himself.

involved2 Not used. Use NULL for this parameter. var1 This is the state to request the stopped object to go into. This variable is necessary only if the TaskExecuter that executes this task may be preempted. It is also only needed if you are using milestone tasks. If this variable is set to 0, then the task will only be executed once, even if it is within a milestone task's range and the object is preempted within that range. If this variable is set to 1 and the task is within a milestone task's range, then the task will be executed again each time the object is preempted and needs to do the task over again. By default, the value is 0, meaning the task will only be executed once. Note that if it is 0, on the first execution of the command, the TaskExecuter will change the variable to 2 as a flag to not execute it again. This is the id for the stopobject command This is the priority of the stopobject command

var2

var3 var4

Example

inserttask(ts, TASKTYPE_STOPREQUESTBEGIN, current)

TASKTYPE_STOPREQUESTFINISH
This task causes the TaskExecuter to call resumeobject() on the involved1 object. Refer to the resumeobject() command documentation for more information. involved1 This parameter specifies the object to call resumeobject() on. involved2 N/A This variable is necessary only if the TaskExecuter that executes this task may be preempted. It is also only needed if you are using milestone tasks. If this variable is set to 0, then the task will only be executed once, even if it is within a milestone task's range and the object is preempted within that range. If this variable is set to 1 and the task is within a milestone task's range, then the task will be executed again each time the object is preempted and needs to do the task over again. By default, the value is 0, meaning the task will only be executed once. This is the id for the resumeobject() command. N/A This variable is managed by the TaskExecuter, and tells whether this task has already been executed once.

var1

var2 var3 var4

Example

inserttask(ts, TASKTYPE_STOPREQUESTFINISH, current)

TASKTYPE_SENDMESSAGE
This task causes the TaskExecuter to send a message to the involved1 object. involved1 Involved1 is the object that the message is sent to. If NULL, then a message is sent to the TaskExecuter himself.

Involved2 specifies msgsendingobject in the message trigger. If NULL, then msgsendingobject is the TaskExecuter himself. Usually this will be involved2 NULL, because it is the only way that you can access the TaskExecuter within the message trigger. However, you may want the message to be sent "from" a different object, so you have the option here. var1 var2 var3 This parameter is passed in as msgparam(1) in the message trigger. This parameter is passed in as msgparam(2) in the message trigger. This parameter is passed in as msgparam(3) in the message trigger.

var4

This parameter tells whether the message sent is to be a delayed message. If 0, then the message is sent immediately. If -1, then the message is sent delayed in zero time. Otherwise, the message is sent in the specified number of seconds. You might think that delayed message sending is a bit redundant, because if you want to send a delayed message, why not insert a delay task followed by a regular send message task. There is a subtle difference. Say, for example, you want the TaskExecuter to wait until a certain number of requirements are met, and the only way you can check those requirements is by executing code. The way that you would do this is, when the TaskExecuter gets to the point where he needs to wait for the requirements to be met, he sends a message to some object, and then either does a utilize task, or a stop request begin task. When the other object gets the message, he is responsible for checking if the requirements are met. If they are already met, then he is to immediately call resumeobject() or freeoperators() on the TaskExecuter. Otherwise he must wait until the requirements are met, and then call resumeobject() or freeoperators(). A problem arises, however, when the requirements are already met and he can immediately allow the TaskExecuter to continue. If the message has been sent immediately, then the TaskExecuter hasn't started the utilize of stoprequestbegin task yet. He is still working on the send message task. So the other object can't immediately call freeoperators() or resumeobject() because he must wait until the TaskExecuter finishes the send message task, and goes on to the utilize or stop request begin. Sending a delayed message in 0 time allows the TaskExecuter to do exactly that, and thus allow the other object to immediately free him if the requirements are met.

Example

inserttask(ts, TASKTYPE_SENDMESSAGE, current, NULL, p1,p2,p3, delay)

TASKTYPE_DELAY
This task causes the TaskExecuter to go into a given state, and then simply wait for a specified amount of time. involved1 Not used. Use NULL for this parameter. involved2 Not used. Use NULL for this parameter. var1 var2 This is the amount of time that the TaskExecuter will wait in the specified state. This is the state into which the operator will go during the delay task. If it is 0, then the TaskExecuter will remain in the previous state it was in. This variable is reserved by the TaskExecuter. Do not set this variable yourself, or at least don't expect it to stay the same as what you specified it to be. N/A

var3

var4

Example

inserttask(ts, TASKTYPE_DELAY, NULL, NULL, time, STATE_NUMBER)

TASKTYPE_MOVEOBJECT
This task tells the TaskExecuter to move a specified object into a specified container. This would be used if you want the TaskExecuter to load/unload a flow item without going through the offset travel or the load/unload time. Also, this could be used if you want a flow item to be moved, but not into or out of the TaskExecuter. involved1 The object to move. involved2 The object to move involved1 into. var1 var2 var4 The output port of the object that involved1 will exit. 0 is usually fine. N/A

Example

inserttask(ts, TASKTYPE_MOVEOBJECT, item, outobject(current, 1))

TASKTYPE_DESTROYOBJECT
This task tells the TaskExecuter to destroy the specified object. Usually this will be done if a flow item is finished in a model, and is ready to go to a sink. You can destroy the flow item explicitly here. You could also use this to destroy labels. Say for example you have a label that acts as a queue of requests. Once a request has been completed, or is ready to be taken out of the queue, you can destroy it. involved1 involved2 var1 var4 The object to destroy. Not used. Use NULL for this parameter. N/A.

Example

inserttask(ts, TASKTYPE_DESTROYOBJECT, item, NULL)

TASKTYPE_SETNODENUM
This task causes the TaskExecuter to set the value on a specified node. This would be used if you want to set a variable or label on the object. involved1 The node to set the value on. This can be something like label(current, "mylabel"). or var_s(current, "maxcontent")

involved2 Not used. Use NULL for this parameter. var1 var2 var3 var4 The value to set the node to. This parameter allows you to either set the value on the node, or increment the value on the node. By default (0), it will set the value of the node. If 1, then it will increment the value on the node by var1. N/A.

Example

inserttask(ts, TASKTYPE_SETNODENUM, theNode, NULL, 42)

TASKTYPE_TRAVELTOLOC
This task causes the TaskExecuter to travel to a specified location using offset travel. involved1 Not used. Use NULL for this parameter. involved2 Not used. Use NULL for this parameter. var1 var2 var3 var4 This is the x location to travel to. This is the y location to travel to. This is the z location to travel to. This is the desired end speed.

Example

inserttask(ts, TASKTYPE_TRAVELTOLOC, NULL, NULL, 3,3,3)

TASKTYPE_TRAVELRELATIVE
This task causes the TaskExecuter to travel a specified offset using offset travel. This is like the TravelToLoc task, except that instead of traveling to a location, the TaskExecuter offsets from his current location. involved1 Not used. Use NULL for this parameter. involved2 Not used. Use NULL for this parameter. var1 var2 var3 var4 This is the x offset to travel. This is the y offset to travel. This is the z offset to travel. This is the desired end speed.

Example

inserttask(ts, TASKTYPE_TRAVELRELATIVE, NULL, NULL, 1,0,0)

TASKTYPE_PICKOFFSET
This task causes the TaskExecuter to execute part or all of the travel offset involved in a load task. This also allows you to sequence the travel operation that the TaskExecuter does before doing a load. Let's say, for example, that you have a floor storage area that the TaskExecuter is going to pick an item from. The items are organize in bays (x) and rows (y) on the floor. When the TaskExecuter arrives at the floor storage area, instead of traveling straight to the product to load it, you want him to first travel in the x direction to the right bay, then travel the y and z offsets to the location of the item. This task type allows you to do this. When the TaskExecuter arrives at the floor storage area, you can give him a pick offset task in which you tell to only travel the x portion of the offset. Then you can give him the usual load task, and he will do the y and z offsets once he's finished with the x offset. If you give an object a pick offset task to travel all of the offsets, the effect will be to do the complete travel operation of a load task, without actually loading the object at the end. involved1 involved2 Just like in a load task, this is the reference to the item that would be loaded. Just like in a load task, this is the reference to the station from which the item would be loaded. These parameters are usually either a 0 or 1. They correspond respectively to the x, y, and z portions of the offset travel. If 0, then the TaskExecuter will travel none of the corresponding offset. If 1, then the TaskExecuter will travel all of the corresponding offset. You can also have these values be between 0 and 1. A 0.9 would mean that the TaskExecuter would travel 90% of the corresponding offset. This is the desired end speed.

var1 var3

var4

Example

inserttask(ts, TASKTYPE_PICKOFFSET, item, current, 1,0,0)

TASKTYPE_PLACEOFFSET
This task is just like the pick offset task, except that it does part of all of the offset travel involved with an unload task. involved1 involved2 var1 var4 Just like in an unload task, this is the reference to the item that would be loaded. Just like in an unload task, this is the reference to the station to which the item would be unloaded. Same as pick offset task.

Example

inserttask(ts, TASKTYPE_PLACEOFFSET, item, outobject(current, 1), 1,0,0)

TASKTYPE_TAG
This task is exclusively for you to use to "tag" your task sequences. Say for example, that you create 5 general types of task sequences in your model. At certain points in the simulation you need to know which general type a certain task sequence is. By inserting a "tag" task as the first task of all task sequences you create, you can then query that task by using the gettaskinvolved() and gettaskvariable() commands. involved1 For your use. involved2 For your use. var1 var4 For your use

Example

inserttask(ts, TASKTYPE_TAG, current, centerobject(current, 1), 1)

TASKTYPE_MILESTONE
This task type is only useful for task sequences that may be preempted. It defines a "bookmark" in the task sequence that the TaskExecuter can revert back to if it is preempted away from the task sequence. Normally when a TaskExecuter is preempted away from a task sequence, it will resume at the same spot it was at once it comes back to the task sequence. The milestone task allows you to tell the TaskExecuter to repeat a whole section of tasks if preemption occurs. The task has a defined range of subsequent tasks for which it is responsible. If the TaskExecuter is within that range and is preempted, then it will revert back to the milestone task. If it has passed the milestone's range, then it will go back to the default preemption functionality. class="note">Note on coordinated task sequences: The milestone task will not work as a proxy task in a coordinated task sequence. If you want to set bookmarks in a coordinated task sequence, then you should insert a CALLSUBTASKS proxy task, and within the subsequent sub-task sequence, you can insert milestone tasks as needed. involved1 Not used. Use NULL for this parameter. involved2 Not used. Use NULL for this parameter. This parameter is the range of the milestone task, defined in number of tasks. For example, if var1 is set to 3, and the milestone task is the 5th task in the task sequence, then if the TaskExecuter is preempted while executing any one of tasks 6, 7 or 8, then it will revert back to the milestone task. N/A

var1

var2 var4

Example

inserttask(ts, TASKTYPE_MILESTONE, NULL, NULL, 3)

TASKTYPE_NODEFUNCTION
This task type will call nodefunction() on the specified node. involved1 The node to call nodefunction() on. Passed in as parnode(1). If specified as NULL, then when the involved2 TaskExecuter executes the task, it will pass a reference to itself as parnode(1). var1 var4 These parameters are passed in as parval(2), parval(3), parval(4), and parval(5) in the nodefunction.

Example

inserttask(ts, TASKTYPE_NODEFUNCTION, node, NULL, 1)

TASKTYPE_STARTANIMATION
This task type will call startanimation(). involved1 Passed as parameter 1 to startanimation(). If NULL, the the TaskExecuter will pass a reference to itself.

involved2 Not used. Pass NULL. var1 var2 var3 var4 Passed as the animation parameter into startanimation(). Defines the rank of the animation to start. Passed as the durationtype parameter into startanimation(). Passed as the durationvalue parameter into startanimation(). Not used. Pass 0.

Example

inserttask(ts, TASKTYPE_STARTANIMATION, NULL, NULL, 1)

TASKTYPE_STOPANIMATION
This task type will call stopanimation(). involved1 Passed as parameter 1 to stopanimation(). If NULL, the the TaskExecuter will pass a reference to itself.

involved2 Not used. Pass NULL. var1 var2var4 Passed as the animation parameter into startanimation(). Defines the rank of the animation to start. Not used. Pass 0.

Example

inserttask(ts, TASKTYPE_STOPANIMATION, NULL, NULL, 1)

TASKTYPE_FREEOPERATORS
This task type will call freeoperators(). This might be used as an alternative or as a supplement to the coordinated task sequence mechanism. It allows you, as part of one TaskExecuter's task sequence, to free another TaskExecuter from a utilize task. involved1 Passed as parameter 1 to freeoperators(). involved2 var1var4 Passed as parameter 2 to freeoperators(). If NULL, the TaskExecuter will pass a reference to itself. Not used. Pass 0.

Example

inserttask(ts, TASKTYPE_FREEOPERATORS, centerobject(current, NULL, 1), NULL);

Note: The following task types are only for reference purposes, you should never insert one of these task types explicitly.

TASKTYPE_TE_STOP
This task is created when you call stopobject on a TaskExecuter. The TaskExecuter creates a preempting task sequence of priority 100000, and inserts this stop task into it. involved1 involved2 var1 var2 - var4 Not used. Use NULL for this parameter. Not used. Use NULL for this parameter. The state that the TaskExecuter should go into when he is down. N/A

TASKTYPE_TE_RETURN
This task is added onto the end of a task sequence that is returned by a call sub tasks task. It ensures that once the task sequence is finished, it will return to the original task sequence This parameter points to the original task sequence to return to. If the involved1 original task sequence is a coordinated task sequence, then this will point to the task sequence with the TE_ALLOCATED task in it. involved2 This parameter points to the actual call sub tasks task as a node. var1var4 N/A

TASKTYPE_TE_ALLOCATED
This is a special task specifically used for coordinated task sequences. The task tells the TaskExecuter to be allocated meaning when the object comes to this task, it will notify the object coordinating the task sequence, and then simply wait until it is told to do something by that coordinator. involved1 involved2 var1 - var4 The object coordinating the task sequence. This is a reference to the coordinated task sequence being executed. N/A

Coordinated Task Types


Note: The following task types should never be inserted explicitly by the user. They should instead be inserted using the insertallocatetask(), insertsynctask(), and insertdeallocatetask() commands.

TASKTYPE_CT_ALLOCATE
Here the task coordinator will try to allocate some TaskExecuter. It is by done by creating a regular task sequence with one TASKTYPE_TE_ALLOCATED task in it, and giving the task sequence to a specified object. This task blocks the continuation of the task sequence until an object has been allocated. This is a reference to a dispatcher to give the task sequence to. It may be a specific TaskExecuter, or, if the object to allocate can one of several involved1 possible objects, then it can reference a dispatcher that dispatches to those task executers. involved2 var1 var2 var3 var4 This is not specified when the task is created, but will be set once the object has been allocated and will reference that object. The priority value for the allocation The preempt value for the allocation This is changed as the task sequence is executed, and is the rank of the front most proxy task that has been given to the allocated resource This tells whether the task sequence is blocking. Default (0) is blocking, 1 is non-blocking

TASKTYPE_CT_SYNC
Here the task coordinator blocks the continuation of the task sequence until some previously specified task (referenced by rank), is finished. involved1 involved2 var1 var2 - var4 Not used. Use NULL for this parameter. Not used. Use NULL for this parameter. The rank of the task to sync to. N/A

TASKTYPE_CT_DEALLOCATE
Here the task coordinator notifies an object that it can finished its allocated task, and resume to other tasks. The object is specified by the rank of the allocation task that allocated it. involved1 Not used. Use NULL for this parameter. involved2 Not used. Use NULL for this parameter. var1 var2 var3 var4 The rank of the allocation task that allocated the object. This variable specifies whether the deallocation task is blocking. Default (0) is blocking. 1 is non-blocking. N/A

TaskExecuter
Overview
This section is provided for users that wish to know more about how the Patients and Resource objects behave. The information here is somewaht advanced but can offer insight into why things happen the way they do and how things work "under the hood". TaskExecuter is the top level class for Patient objects as well as the reources such as Staff, Equipment and Transports. All of these objects can travel, load flowitems, unload flowitems, act as shared resources for processing times, and perform many other simulation tasks.

Details
TaskExecuters and their sub-classes are able to execute task sequences, perform collision detection, and execute offset travel. When the TaskExecuter receives a task sequence, it first checks to see if it already has an active task sequence. If there is no active task sequence, or if the newly received task sequence is preempting and has a priority greater than the currently active task sequence, then it will start executing the new task sequence, preempting the active one if needed. Otherwise it will go through the normal Dispatcher logic. If the task sequence is not passed on immediately, then it will queue up in the TaskExecuter's task sequence queue, and if the task sequence is still in the queue when the TaskExecuter finishes its active task sequence, the TaskExecuter will then execute the task sequence.

User-Defined Properties
All TaskExecuters have the following fields that can be defined by the modeler. Capacity: This parameter defines a value for the maximum content of the object. In default operation, the object will never load more flowitems than this value specifies. Note for advanced users on the capacity value: this value can be deceiving if you create your own task sequences. Since the TaskExecuter's first and most important responsibility is to execute task sequences, if you give the object a task sequence to load more flow items than its maximum content, then it will load the flowitems anyway. The only real instance in which the maximum content value is used is for the TASKTYPE_BREAK task. If the TaskExecuter comes to a break task, and it has reached its maximum content, then it will not perform the break, and will continue on its current task sequence instead of breaking to another task sequence. This works in the default case when task sequences are created automatically because each task sequence is responsible for the loading of just one flowitem.

Maximum Speed, Acceleration, Deceleration: These define the TaskExecuter's maximum speed, acceleration, and deceleration. Maximum speed is defined in units of length per unit of time, while acceleration and deceleration are defined in units of length per squared unit of time. If you are defining your model in meters and seconds, for example, the speed value is in m/s, etc. These values are used in defining the object's peak speed and change in speed while executing the task types such as TASKTYPE_TRAVEL, TASKTYPE_TRAVELTOLOC, etc. Travel Offsets for load/unload tasks: This value determines whether the TaskExecuter should execute offset travel to the load/unload location when it loads or unloads a flowitem. For example, if this is not checked, and the TaskExecuter is traveling on a network, then it will only travel to the network node that is at the load/unload station. It will remain on that node while doing the load. Rotate while traveling: Here you can specify if you want the object to rotate in the direction that it is traveling. This will have no effect on model output. It is only for visual purposes. Load Time: This field is executed at the beginning of each load task. Its return value is the delay time that the TaskExecuter will wait before loading the flowitem and moving on to the next task. Note that if the TaskExecuter is configured to travel offsets for load/unload tasks, then it will first travel the correct offset, and then start the load time. Thus the load time is added onto the end of the offset travel time; it is not part of the offset travel time. Unload Time: This field is executed at the beginning of each unload task. Its return value is the delay time that the TaskExecuter will wait before unloading the flowitem and moving on to the next task. Note that if the TaskExecuter is configured to travel offsets for load/unload tasks, then it will first travel the correct offset, and then start the load time. Thus the load time is added onto the end of the offset travel time; it is not part of the offset travel time. Break to Requirement: This field is executed when the TaskExecuter comes to a break task or callsubtasks task. The return value is a reference to a task sequence. The logic within this field should search the TaskExecuter's task sequence queue, and find a task sequence that is appropriate to break to.

States
The TaskExecuter's states are purely dependent on the types of tasks that the TaskExecuter performs. Many tasks are associated with a hard-coded state, but with some tasks the modeler can specify an explicit state for the TaskExecuter to be in when executing that task. Here are some of the states that you will see often with a TaskExecuter. For more information on tasks and task sequences, refer to Task Sequences. Travel Empty: The object is traveling to a destination object and doesn't contain any flowitems. This state is exclusively associated with the TASKTYPE_TRAVEL task. Travel Loaded: The object is traveling to a destination object and has load one or

more flowitems. This state is exclusively associated with the TASKTYPE_TRAVEL task. Offset Travel Empty: The object is performing offset travel and doesn't contain any flowitems. Offset Travel Loaded: The object is performing offset travel and has loaded one or more flowitems. Loading: The object is loading a flowitem. This state corresponds to the TASKTYPE_LOAD task, and applies only to the time when the object has finished its offset travel and is waiting its modeler-defined load time before loading the item. Unloading: The object is unloading a flowitem. This state corresponds to the TASKTYPE_UNLOAD task, and applies only to the time when the object has finished its offset travel and is waiting its modeler-defined unload time before unloading the item. Utilize: The object is being utilized at a station. This state is usually used for an operator, when the operator has arrived at the station and is being utilized for a process, setup, or repair time. The utilize state is usually associated with a TASKTYPE_UTILIZE task, but that task can also specify a different state. Also, other task types, like TASKTYPE_DELAY, can use the utilize state. Blocked: The object is currently traveling, but is blocked on the network.

Offset Travel
Offset travel is a mechanism by which different types of objects can travel differently, yet use the same interface for traveling. For example, an object wants to place an item into a given bay and level of a Rack. The way in which the object travels to the correct location to drop off the item depends on the type of object it is. An operator walks to the bay's location and places the item in the level. A Transporter travels to the bay, but must also lift its fork to the proper height of the level. It can travel in both the x and y direction, but only its fork can travel in the z direction. An ASRSvehicle will only travel along its own x axis, lifting its platform to the height of the level, and then pulling the item from the Rack. Hence, each object implements its travel differently, but the interface is the same: travel to the right spot to place the item in the Rack. Offset travel is essentially the only thing that distinguishes each sub-class of the TaskExecuter. For information on how each sub-class implements offset travel, refer to the "Details" section of an object's help page. Offset travel is used in load and unload tasks, in traveltoloc and travelrelative tasks, and in pickoffset and placeoffset tasks. The offset travel interface is very simple. Every type of offset request translates into an x,y, and z offset distance, and sometimes a reference to a flow item. For example, if an object is given a traveltoloc task for the location (5,0,0), and its current location is (4,0,0), then it automatically translates that task into an offset request for (1,0,0), meaning it needs to travel one unit in the x direction. A travelrelative task translates directly. For example, a travelrelative task for (5,0,0) tells the object to travel 5 units in the x direction. Load and unload tasks also use offset travel if the "Travel Offsets

for Load/Unload Tasks" checkbox is checked. When an object needs to load a flowitem from a station, it queries the station for the location of the item. Also, when it needs to unload an item, it queries the station for the location to unload the item. The station returns an offset x/y/z distance, and the TaskExecuter uses this distance to travel its offset. Also, for a load and unload task, the TaskExecuter has a reference to the item in its offset request. This may or may not affect the way the object travels, depending on the type of object. For example, the Transporter's offset travel mechanism is implemented so that if there is an item, or in other words, if the Transporter is loading or unloading an item, the Transporter will lift its fork in the z direction. If there is no item, or in other words, if the Transporter is doing a traveltoloc or travelrelative task, then it will actually travel in the z direction, instead of lifting its fork. Offset values should be calculated relative to the x/y center of the object, and the z base of the object. For example, a robot is positioned at location (0,0,0). It has a size of (2,2,1). From this the x/y center and z base can be calculated as the location (1,-1,0) (Note: y size extends along the negative y-axis). All offset calculations should be made from this (1,-1,0) location. While giving the robot a traveltoloc task will automatically make this calculation for you, sometimes it is necessary to calculate this location manually and use a travelrelative task. If the robot is given a travelrelative task of (1,0,0), this means that the correct position to travel to is one unit to the right of the robot's x/y center and z base. This translates to the location (2,-1,0). Note that this does not mean that the robot will travel such that its own location is (2,-1,0). Neither will it travel such that its x/y center and z base are at that location. Because it is a robot, it will rotate and extend its arm so that the end of the arm is at the location (2,-1,0). Its actual location will not change at all. Thus the calculation from the object's x/y center and z base allows you to specify a desired destination location which is the same for all objects, but which allows each type of object to handle that destination location differently.

Collision Detection
The TaskExecuter and its sub-classes have the capability of detecting collisions with other objects. Collision detection is performed by adding collision members to a TaskExecuter, then adding collision spheres to it and its collision members, then executing logic when one of the spheres of the TaskExecuter collides with one of the spheres of one of its collision members. Each collision sphere you specify has a location in the TaskExecuter's frame of reference, and a radius. The TaskExecuter repetitively checks for collisions at time intervals that you specify. At each collision check, the TaskExecuter checks for collisions on all of its collision spheres with all of the collision spheres of all of its collision members. If a collision is found, then the TaskExecuter fires its collision trigger. It does not fire the collision trigger of the object with whom it is colliding. The other object's collision trigger will fire if and when it does its own collision checks. Note that the collision trigger fires for a

specific sphere-to-sphere collision. This means that within one collision check the collision trigger can fire several times, once for each sphere-to-sphere collision encountered in the check. Be aware that you can very easily cause your model execution speed to decrease significantly if you are not careful with collision detection. For example, if a TaskExecuter has 5 collision spheres and 5 collision members, and each of its collision members has 5 collision spheres, then each collision check will need to check for 125 sphere-to-sphere collisions. If all 6 TaskExecuters are checking for collisions, then 750 sphere-to-sphere checks are being made at each collision check interval of the model. This can slow the model down considerably, especially if your collision interval is very small. You can turn collision detection on and off for a given TaskExecuter by using the setcollisioncheck() command. See the command summary for more information on this command.

FlexSim Task Sequences


What is a Task Sequence?
A task sequence is a series of tasks to be executed in sequential order by a TaskExecuter, as shown in the figure below. The term TaskExecuter implies any object that inherits from the TaskExecuter class. This includes Operators, Transporters, Cranes, ASRSvehicles, Robots, Elevators, and other mobile resource objects. An object is a TaskExecuter if the TaskExecuter tab page options are in its Properties window.

In addition to being a series of tasks, each task sequence has a priority value, which defines the importance of executing that task sequence with respect to other task sequences. Each task sequence also has a preempt value, which defines whether that task sequence should cause other task sequences' execution to be halted in order to execute this task sequence.

Automatically Created Task Sequences


FixedResources have a default mechanism for creating task sequences to move flow items to the next station. You can use this default functionality by checking the "Use Transport" box in the Flow tab page of the FixedResource's Properties. Processors also have a default mechanism for creating task sequences to call operators for setup times, process times and repair operations. This is done by modifying the Processor or ProcessTimes tab page on a Processor, Combiner, or Separator. Each of these default mechanisms triggers a task sequence to be automatically created.

How Task Sequences Work


When you check the "Use Transport" field on a Flow tab page, the following task sequence is created. 1. 2. 3. 4. Travel to the object currently holding the item Load the item from that object Break Travel to the destination object

5. Unload the item to the destination object

When a TaskExecuter executes this task sequence, it will execute each task in order. Each task mentioned above corresponds to a specific task type. Notice in the above example that there are two "Travel" task types in the task sequence, one "Load" task type, one "Unload" task type, and one "Break" task type.

Travel Task
The "Travel" task type tells the TaskExecuter to travel to some object in the model. This may be done in several different ways, depending on the model's setup. If the TaskExecuter is connected to a network, then the travel task will cause it to travel along the network, arriving at a network node that is connected to the desired destination object. If the TaskExecuter is a Crane object, then it will lift up to a modeler-defined height, then travel to the X/Y location of the destination object. Hence, a travel task can imply several things, depending on the setup of the model, as well as the type of object that is being used. The one thing, however, that all travel type tasks have in common is that they all have some destination object in the model that they are trying to get to.

Load and Unload Tasks


The "Load" and "Unload" task types tell the TaskExecuter to load or unload a flow item into or out of a station. This usually involves traveling an offset distance in order to pick or place the item at the right spot, as well as going through a modeler-defined load or unload time before transferring the item. While the load/unload time is handled in the same way for all TaskExecuters, the offset travel may differ depending on the type of TaskExecuter. A Transporter, for example, will travel to the pick/place location while lifting its fork up to the pick/place height. A robot, on the other hand, will rotate to the spot where the item should be picked/placed. For more detail, see offset travel.

Break Task
The "Break" task type tells the task executer to check if there are any other task sequences that it can "break" to. For example, if a transporter has two items that are waiting to be picked up from the same location, and it has the ability to load two or more items, then the transporter would have two task sequences to do. Both of them would be like the above mentioned task sequence. One is the active task sequence to pick up the first item, and the other task sequence is placed in his task sequence queue to be executed once he finishes the active task. The break task allows the transporter to stop the first task sequence after he has loaded the first item, and begin the second task sequence, which is to travel to the second item's station and load the second item. If the task sequence did not contain the break task, the TaskExecuter would have to

finish the first task sequence completely, unloading the first item before being able to load the second item.

Operator Task Sequences


Here's another example of an automatically created task sequence. The Processor object creates this task sequence to request an operator to work at the processing station. The task sequence is described as follows: 1. Travel to the processing station 2. Be utilized until freed from the processing station.

As in the previous example, the first task tells the TaskExecuter to travel to the station. The second task is a new task type not mentioned in the previous example. This is a "Utilize" task type. It tells the TaskExecuter to go into a given state, like "Utilized" or "Processing", and then wait until it is freed from that state. The operator is freed when the freeoperators() command is called. Since the Processor automatically creates this task sequence, it automatically handles freeing the operator as well. Note: an operator task sequence is not created exactly as described above. In reality there are more tasks added. For simplification purposes, though, we present the above example. For more information on the operator task sequence, refer to the documentation on the requestoperators command in the command summary. At any given time in a simulation, a TaskExecuter can have one active task sequence as well as a queue of waiting task sequences. A Dispatcher object, on the other hand, can have a queue of waiting task sequences, but cannot actively execute any of those task sequences. Rather, it dispatches its queue of task sequences to TaskExecuters connected to its output ports. This is what distinguishes the Dispatcher object from the TaskExecuter and its sub-classes. Active Task Sequence

Queue of Waiting Task Sequences

If no task sequences are preempting, then a TaskExecuter will execute its active task sequence until that task sequence is finished. Then it will make the first task sequence in its queue the active task sequence and start executing that one. This repeats until all task sequences in the queue have been executed.

More Task Types


At this point you have been introduced to 5 task types, namely travel, load, unload, break, and utilize. There are several more task types that can be used when creating task sequences. For a more detailed explanation of each task type and its usage, see Task Types. The next section will address how to create and customize your own task sequences.

You might also like