Falcetto
Rapid Prototyping of Computer Simulations
Introduction
History
Modeling
Simulation
Server Side
Visualization
GUI
Community

Modeling – How to represent a system

 

Atoms, Classes, Instances

                An Atom is the most basic Element, which has no pre-conceptions about what it is, or what it is supposed to do.  An Atom has one Code segment per phase (initialization, time step, Messaging, Convergence), and has whatever Variables the User chooses to put on it.  An Atom Node represents an object, while an Atom Edge represents the connection between objects.  Both Nodes and Edges are considered Elements, and both can be turned into Classes.

                A Class is a collection of Elements, and imparts a concept of what it represents, but is itself not an Element.  This groups the Elements together, and allows duplicate groups to be easily created.  For example, Elements may represent things like tires, axels, and bumpers for a Class that represents an automobile.  This allows the User to put automobiles into their simulation, and only have to worry about creating tires the one time they originally created the car Class.  A Class has two Code segments per phase, one that runs before each Element’s Code, and one that runs after.  The Class can read the Variables of the Elements it contains (unless set not to), allowing it to observe and react to the values in those Variables.  If acting as a Node Class, the Class will expose Nodes for outside connections.  If acting as an Edge Class, it will provide dangling Edges that allow it to connect to two Nodes (while conceptually possible to model 3+ dangling Edges, it would be confusing to view in a GUI sense, and such a requirement of 2 dangling Edges will be imposed).

                A Class Instance is an individual usage of a Class, which exists as an Element.  For example, each Instance of an automobile Class would be a separate automobile within a city model.  Each Instance keeps track of its own Variables, including keeping separate track of the contained Elements.  Class Instances can be Elements within other Classes.  For example, a radio Class Instance could be part of the automobile Class, thus allowing every automobile Class Instance to be able to use a radio.

Specialized Class Instances

                A Specialization is a Class Instance that has different behavior (Code and/or Variables) than the Class it is an Instance of.  Creating Specializations is one of the focal points of Falcetto.  In most simulations, all of the Class Instances will behave the same, but occasionally something needs to deviate from normal behavior.  Many terms can be loosely applied to these Specializations, such as heroes, deviants, aberrations, or anomalies, depending on one’s perception of how the different behavior compares to normal behavior.

One example of a Specialization: the typical automobile will obey speed limits, but a Specialization may have different code which causes it to have aberrant behavior and go over the speed limit.  Traditionally, the User would be required to build the Specialization’s code into the automobile Class, and then add a Variable to turn the behavior on/off.  Falcetto does not prevent the traditional approach from being done, but does allow the alternative of just adding Code as Specializations.  The GUI will make Specializations appear differently, so that they can easily be spotted, as they are often a focal point of a simulation, such as “does the automobile that breaks the law get to their destination sooner?”  Consider also that Specializations, being Elements, can then be put into a new Class, in this example it would be a “speeding automobile” Class rather than the normal “automobile” Class.  Once the Specialization is inside of a Class, creating Instances of the new Class will not appear as Specializations, so in this example they can then blend into traffic unnoticed.

Another example of a Specialization:  an electric power grid is operating normally, now you want to see what happens when a power line goes out, and later comes back on.  Normally this would require adding an array based on/off triggering system to the class, then assign array values to the power line, and then do something to the line to remember which one you changed (maybe recolor it, if color is not used for anything else).  With Falcetto, you’ll create a Specialized line by just adding extra code like “if (TimeIs(10)) { active = false; } else if (TimeIs(60)) { active = true; }”, and Falcetto will handle the highlighting the line so that you can tell you gave it Specialized logic.

 

Socketing, restricting Edge and Node attachments

                Simulating a social network may allow a Node to connect to hundreds or thousands of other Nodes, but simulating something physical, like an electrical outlet, has very limited connections.  A Node Element can be configured to limit the quantity and types of Edge connections that it can make.  Using the electrical outlet example, a typical outlet only allows 2 connections of 110V appliances, and thus is unable to accept a 3rd connection, nor can it supply power to 220V appliances.  These limitations are based on the available Edge Classes.

 

Creation/Destruction of Elements

                Falcetto allows the Code to dynamically create Class Instances, and to destroy Elements.  Newly created Instances will not participate in the current processing cycle, but will instead come to exist after all processing is completed.  Destroyed Elements will live out the rest of the current processing cycle, and cease to exist after processing is completed.  Code is not allowed to create or modify Code, so most dynamic creations will likely be Class Instances, which will have their Class Code to perform processing.  Since Code is not allowed to be created or modified, Code is not able to create Aberrations.  The User could always pause the Simulation, use the GUI to add/remove Elements, and turn Instances into Aberrations, but such actions are considered part of the Simulation, and such changes will not become part of the Model.  Instance creation can also fail, for example, trying to create a 50kV power line to connect to a 100kV transformer.  Creating or destroying Elements will be allowed from anywhere, but a good coding practice would be to only do so from Class or Global logic, as those spaces would have the best awareness of what needs to be created or destroyed.

                The initialization code phase is a great place for dynamically creating Elements.  This allows the User to have a clean workspace during editing, then use code to populate the Model once the Simulation starts.  For example, creating a 20x20 grid of patches of grass would require creating 400 Instances of the patch of grass Class, which would take a long time to do manually, but only two loops and a function call in the Code to do during the initialization phase.

 

Code Locations

                Code segments, and the Variables they rely on, can exist in many places within Falcetto, allowing the User the freedom to define their model however they want:

·         On the Global space, where they are available for use by any Element of the model.

·         Within Class definitions, and thus be available for each Instance of that class.

·         On the Atoms and Instances that live within a Class definition.

·         On individual Instances of a Class.

·         On individual Atoms.

                The Global space and Atoms only have one place for their Variables and Code to live, but Class Instances have two places.  Within the Class they have the Variables and Code that are part of the class, while as an Instance they can have their own Variables and Code as well.

This demonstrates how the Global space (top) and Atoms (bottom) have only 1 surface for Code, while Class Instances (middle) can have multiple surfaces for Code.

                Class Instances have two Code segments that can be run for any particular phase of processing.  The phases of processing are initialization, time step simulation, Message handling, and Convergence.  One Code segment is run before the Class Code is run, while the other Code segment is run afterwards.  This allows a Class Instance to prepare data for the Class to use, and/or react to the data changes that the Class made.

 

Variables

                Each Variable has its own personal settings.  The Variables can be of certain types, such as: number, words, or object.  Each type will have its own options, such as the number having options including: integer, decimal, real, imaginary, complex, positive only, and negative only.  Each Variable can have its own accuracy settings for Dynamic time step determination, allowing for models with Elements on different scales without sacrificing speed or accuracy.

                By allowing Variables to have different accuracy settings, a model can allow vastly different objects to interact.  Imagine a mouse and an elephant are having a race in your simulation.  A change of 1 millimeter may be accurate for the mouse, but too small for the elephant, while a change of 1 meter may be accurate for the elephant, but too big for the mouse.  Traditionally, the simulation would need to choose which scale to use, or the User would need to add Code to do the scaling change (“Normalization”).  Falcetto allows the User to select the accuracy for each Variable, and then performs the “Normalization” automatically.  Another, more likely scenario would be that the objects within a Class have a different accuracy than the Instances of the Class would, such as a Class representing the life crawling around on a planet, while the Instance represents the planet hurtling through the cosmos.

Variables can be “promoted” from being just on an Element, to being a Class Variable.  This allows the Variable to be seen by anything that can see the Class’s Variables, as well as be directly altered by Aberration (Class Instance) Code.  This will force some of the parallelism to be unavailable for the Instances of the particular Class, so frequent use of Variable promotion may lead to slower processing times when using Server Side processing.

Variables are visible to any Element that is in the same space as the Element, Class Variables are available to Elements that are contained by the Class, and Global Variables are available to every Element.  This visibility can be turned off though, for situations such as a class in Control Theory, or for Black Box models.

                Elements will have some pre-existing Variables available, such as color, location, size, and direction.  These Variables are always available for an Element, and are directly reflected in the way the Element appears.  Using visual cues is an intuitive way to impart aspects of a Model.  For instance, the color of an object can be used to display Model aspects such as hot or cold, wolf or sheep, happy or sad, red team or blue team, good driver or bad driver, and most any other important aspect of the Model.  Edge Elements and Node Elements will have different pre-existing Variables available.

                The pre-existing Variables will have special options available, but will require the User to choose to use the special option.  Consider how “direction” is usually determined by how the object has been moving, so it has an option to automatically determine the direction, with a further option to automatically update the direction’s “up” vector as well.  Consider how “size” would be used in a chemistry Model: is an atom’s size its nucleus, or its electron cloud, or are we used to a size in-between?   To make this work intuitively, the size Variable has the option to use a different display size.  This allows the Helper functions that use the size for proximity and collision detection to use the actual size (electron cloud), while the UI shows the smaller image for the atom.  Edges similarly will need to be aware of various lengths, as they will need to know the displayed length, the length between the Nodes’ logical sizes, the length between the Nodes’ actual sizes, and the length if measured from the center of the Nodes.

                The Element will have its own unique name within its space, and can be assigned to groups.  This name will be automatically assigned at creation of the Element, but can be changed.  The name is used to make more readable charts, help identify where bugs in the Code are, and by Helper functions to specify which Element to use data from.  Giving an Element a group value will allow Helper functions to perform their function on multiple Elements using a single command.

 

Messaging

                Elements are not allowed to modify each other’s Variables, which requires a way of communicating to each other so that they can change their own Variables based on influence from other Elements.  The User can craft their own communication method by using the available Variables, or they can use the Messaging system.  The Messaging system will allow an Element to send a message, with an optional delay, to another Element.  During the Message handling phase of processing, the Element chooses what to do with each message.  Like Convergence, several Message handling cycles may occur for any single time step cycle, as any new Messages that are sent with no delay will need to be processed.

As an example, the User wants to simulate (without using Helper functions) the momentum change as a marble rolls into another object.  Upon collision, the marble says “hey, you need to move, I weigh 1 ounce, and am moving at 2mph North.”  If the other object is a piece of dust, then it will choose to move, but offer no resistance to the marble.  If the object is another marble, it may say “okay, I am moving, but I weigh 1 ounce, and was moving 1mph South, so you slow down.”  If the object is a wall, it may say “I am not moving, you bounce off of me, and my angle is 45 degrees.”  In this scenario, the messages consist of technical information, such as mass and movement vector, as well as a communication of intent.  During the next Message cycle, the marble would adjust its own movement vector as appropriate to the response it received from the item it collided with.  In these situations, the Messages would be sent with no delay, so they would be received and processed during the same phase.

                Messages can be sent with delays, to simulate the delays that would be experienced on a real transmission medium, or they may be sent with no delays.  When sent with no delay, the Message will be queued up on the receiving object, and processed during the same processing cycle.  When sent with a delay, the time step determination functionality will take into account when the message is supposed to arrive, and ensure that a time step occurs directly at that instant.

If Message delivery is being used as part of your Model, consider how a real message would travel.  Messages usually travel over a medium, such as a wire, thus a Node Element sending the Message with no delay to an Edge Element, which then sends it to itself with delay, and then sends it without delay to a Node Element would be the most accurate way of simulating the Message delivery.  This would also allow the Edge Element to simulate noise or failures during transmission, such as the line getting cut while a message was being transmitted.  Such logic would not live in a Node Element, which is concerned with processing the Message, but instead would live on the Edge Element, which is concerned with transmitting the Message.

 

Helper Functions

                Object Variables will have several Helper functions available to help with intuitively manipulating them.  The pre-existing Variables (color, location, size, direction, etc.) will typically be object types.  The color Variable will be stored as RGB values, but HSV and CYMK values can be useful for different purposes, so Helper functions will be available to let the User work with the color as they want to.  The direction Variable on a Node Element will be a 3D vector, so Helper functions will be available for doing vector and matrix math, as well as rounding the data to simpler ordinates.

                Physics helper functions will include functionality for collision detection and handling.  Detecting whether a collision occurred will use bounding spheres and bounding rectangles.  Depending on stretch goals, functions may exist to use the 3D model data to perform collisions as well.  These detection functions take into account recent changes in Node locations and directions in order to determine the vectors of collision and vectors of ricochet.  These vectors can then be used by other helper functions to determine changes in Node speed or direction.  The User may not even need to see these vectors, as the vectors can be cached and made available to other helper functions.

                Math helper functions will include matrix and vector math functionality, as well as complex number processing.  A third party math library will be utilized, licenses permitting, or built otherwise.  Vector normalization is quite useful for determining precise directionality, and will be utilized internally by Falcetto for many graphical actions.  In addition to the vector operations available in the math library, some functions will exist to convert a vector into something familiar like a compass direction, which can be used for text displays.

                Graph modeling can often benefit from clustering logic.  These helper functions will help to organize the Node data into clusters and groups that are closely related or connected by Edges.   These functions will provide suggestions of where a Node should relocate itself to be closer to its proper cluster, and farther from clusters it doesn’t belong to.  A GUI component exists to run this functionality outside of the simulation, in order to organize your Model without needing to include the logic in Code segments.

                Falcetto will allow the User to specify JS files to include throughout their Model.  Due to restrictions of browsers, the User may need to copy-paste the contents of the JS file into Falcetto.  Falcetto can then remember the file, and make it available for other projects, both online and offline.  Browser plug-ins or Server Side subscriptions may help simplify the process.

 

Debugging

                Web browsers on computers all come with debugging functionality for JS code, and Falcetto will provide functionality to help facilitate the use of these tools.  Since Falcetto is acting as a framework for programming computer models, it will need to provide a good interface to the underlying debugging capabilities, but also provide some of its own tools to help the User.  Debugging tools are not pleasant for new programmers, as they are often quite complicated, and even experienced computer programmers can be surprised by debugging features they are unaware of.  Falcetto will provide functionality to help the User perform common debugging tasks without needing to use the browser’s debugger, and other functionality for when using the debugger is necessary.

The expected User is a student that may be using Falcetto as their first introduction to computer programming, meaning that they may make many mistakes.  Falcetto will always run the User’s code in try-catch statements, in order to catch any thrown exceptions.  When an exception is caught the Simulation will pause, invalidate the cycle, select the Element that possesses the offending Code, and inform the User of the reported error.  Falcetto will possess a series of help documentation for known JS errors, with advice on why the error occurs and how to fix it.  When an error occurs, Falcetto will accompany the popup with the help documentation that would seem appropriate for the error.

The “debugger” JS command tells the browser’s debugger to pause the code on that line of code.  Falcetto is at the mercy of this command, but at the same time benefits from the “free” debugger that is provided by the browser.  Falcetto will examine Code segments, in order to know that a Code segment may result in Falcetto being paused against its will.  This may result in the modification of the User’s code in order to include a Falcetto function call to inform Falcetto that the simulation was indeed paused by a debugger command.  This knowledge will allow Falcetto to pause the Simulation immediately afterward, allowing the User to fix the Code segment before resuming the Simulation, or at the very least prevents the “debugger” command from being run many times before the User has a chance to act.  The User will have the option of restarting the current processing cycle, or to start using the new Code changes with the next processing cycle.

Infinite loops are a dangerous hazard in computer programming, but also an unavoidably common pitfall for new programmers.  An infinite loop, or other similar error, will cause the browser to terminate code execution, including the Falcetto components involved.  Falcetto’s code isolation takes this into account, and will detect when a Code segment was forcibly terminated by the browser.  When this is detected, Falcetto will attempt to inform the User, as though the error were a normal caught exception.

Falcetto will perform many auto-save operations throughout a simulation, on the off chance that a browser terminates the framework, or the browser closes without warning.  When Falcetto resumes, it will inform the User of where it was when it was suddenly shut down.  This will allow the User to resume an in-progress Simulation, or discover bugs that were not handled by the Falcetto framework.  If participating in the PIP, these types of application restarts will have a special priority for analysis.

Each processing cycle has the potential for running many times over, possibly without end.  Dynamic time step processing cycles will be discarded and reprocessed whenever accuracy bounds are exceeded.  Messaging processing cycles could keep sending “no delay” messages between Elements such that an infinite loop occurs.  Convergence processing cycles may find themselves in a situation where convergence will not occur, and the values never stop changing.  Falcetto will survive these situations, and provide the user with a description of which processing cycle experienced a problem, and the Element and Code segment that seems to have caused the problem.



Content ©2014-2017 Ether Tear LLC. Website powered by Ether Tear LLC, ©2013-2017