Help
  • Explore Community
  • Get Started
  • Ask the Community
  • How-To & Best Practices
  • Contact Support
Notifications
Login / Register
Schneider Electric
Community
Community
Notifications
close
  • Categories
  • Forums
  • Knowledge Center
  • Blogs
  • Ideas
  • Events & Webinars
Help
Help
  • Explore Community
  • Get Started
  • Ask the Community
  • How-To & Best Practices
  • Contact Support
Login / Register

Contact Support

Close

Ask our Experts

Have a question related to our products, solutions or services? Get quick support on community Forums

Email Us

For Community platform-related support, please email us

New Community Ranking System
Our Community ranking system has recently been updated. You may notice changes in user rankings and receive system messages or notifications. If you have questions about how the new ranking works, please refer to the announcement post for more details (click here).

Digital Twin

This knowledge base is addressing usage of software Experior, Machine Expert Twin and future Automation Expert Twin. These softwares are used to create smaller instances of digital twins for use in industrial automation, warehouse management, design & engineering with more..

Search in

Improve your search experience:

  • Exact phrase → Use quotes " " (e.g., "error 404")
  • Wildcard → Use * for partial words (e.g., build*, *tion)
  • AND / OR → Combine keywords (e.g., login AND error, login OR sign‑in)
  • Keep it short → Use 2–3 relevant words , not full sentences
  • Filters → Narrow results by section (Knowledge Base, Users, Products)
cancel
Turn on suggestions
Auto-suggest helps you quickly narrow down your search results by suggesting possible matches as you type.
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Select a Country

Please select a country to continue with beta search.

  • Home
  • Schneider Electric Community
  • Knowledge Center
  • Digital Twin
  • Digital Twin
  • Label: Experior 6
Options
  • Knowledge Base Article Dashboard
  • Subscribe
  • Bookmark
  • Invite a Friend
Invite a Co-worker
Send a co-worker an invite to the portal.Just enter their email address and we'll connect them to register. After joining, they will belong to the same company.
You have entered an invalid email address. Please re-enter the email address.
This co-worker has already been invited to the Exchange portal. Please invite another co-worker.
Please enter email address
Send Invite Cancel
Invitation Sent
Your invitation was sent.Thanks for sharing Exchange with your co-worker.
Send New Invite Close
Labels
Top Labels
  • Alphabetical
  • Experior 6 85
  • Experior 7 57
  • Exp-6 Developer Guide 35
  • Exp-7 Developer 16
  • Exp-6 User Guides 16
  • Exp-7 Communication Protocols 11
  • Exp-6 Experior 11
  • Exp-6 Communication Protocols 11
  • Exp-7 Getting Started 10
  • Exp-6 Dev Environment 9
  • Exp-7 User Interface 9
  • Exp-6 Dev Assembly 7
  • Exp-7 Building Models 6
  • Exp-7 Working With Models 5
  • Exp-6 PLC 4
  • Exp-6 Getting Started 3
  • Exp-7 Importing Graphics 3
  • Exp-6 3rd Party Programs 2
  • Exp-6 Tips and Tricks 2
  • Remote Viewer 2
  • Exp-6 Model Modifications Examples 1
  • Previous
  • 1 of 3
  • Next
Top Contributors
  • Kasper.Vestrup
    Kasper.Vestrup
See More Contributors

Related Forums

  • Intelligent Devices Forum

Previous Next

Invite a Colleague

Found this content useful? Share it with a Colleague!

Invite a Colleague Invite

Label: "experior 6"

View in: "Digital Twin" | Community

85 Posts | First Used: 2026-01-09

Digital Twin

Sort by:
Likes
  • Date
  • Views
  • Likes
Options
  • Knowledge Base Article Dashboard
  • Subscribe
  • Bookmark
  • Invite a Friend
  • « Previous
    • 1
    • 2
    • 3
    • 4
    • 5
  • Next »
Label: "Experior 6" Show all articles

Setting up URSim with Experior 6

Before you start, make sure you have the Universal Robots Experior catalogs: • Experior.Catalog.UniversalRobots.dll • UniversalRobotsCommunication.dll   Afterward, follow these steps   Robot controller connection The following steps will connect the Experior URX assembly to the robot controller in URSim.   1. Place the Experior UR catalog (.dll) files in the Experior 6 installation folder (usually C:\Xcelgo\Xcelgo Experior 6).   2. Download and unpack/install the following: a. UR Non-Linux Offline simulator virtual machine (URSim):  b. VMware Workstation Player    3. Open VMware Workstation. Open the URSim virtual machine (Player-File-Open, then browse the file explorer to where you unpacked the files from 2.a., then select the .vmx file).    4. When the virtual machine is running, open the file with the name of the robot that you want to simulate. Then, turn the virtual robot on using the button on the bottom left. Then click ON and START.   5. Open Experior 6.0. Make sure the UniversalRobots catalog is selected in the catalog selector. Drag and drop the desired robot from the Catalogs panel to the model.   6. Go to URSim and open the robot settings.   In the settings menu, select System-Network. Note the URSim IP address.   7. Connect URSim to Experior. Do this by going to your Experior model, selecting the robot, and writing the URSim IP address in the IP Address field, under Robot connection. 7.1 Afterward, right-click on the robot and select Connect to robot controller. After this, the robot in Experior will snap into the position of the robot in URSim.       After this, the robot in Experior will replicate the trajectory of the robot in URSim.   Connecting robot I/O through Modbus TCP The following steps show how to connect the robot I/O through the URSim Modbus server and the Experior Modbus client.   1. In URSim, go to Installation- Fieldbus- Modbus- Add a new signal. (Initially, the variable list will be empty) In the dropdown menu, select the variable type: Digital Input/Output, Register (byte) Input/Output. Rename the variable (this is the name that will be used in the UR programming interface)   2. Assign the memory address for the variable. For this, you need to take into account that all the addresses have specific uses (see here).   3. In Experior, add the Modbus client by right-clicking the Communication panel, and selecting Modbus.     4. Select the Modbus client, and in the Properties panel, write the URSim IP address in the IP Address field, under Communication.     5. Assign Input/Output variables to the desired components. To do this, first set the Connection id to the id corresponding to the Modbus client. Then, assign the memory address of the Modbus server (assigned in step 2) in the Address field for the specific Input/Output. Modify the Register value, depending on the variable type defined in step 2. For Register Inputs/Outputs, Modify the Size value to UInt16 (WORD).   6. After all the memory addresses have been set in Experior, right-click on the Modbus client and click connect. While the connection is active, you won´t be able to modify the associated I/O in Experior.     After this, the variable values will be represented in the Experior model.   (This example was made with the Display assembly, found in the Advanced catalog)   
View full article
Kasper.Vestrup Explorer
‎2026-01-09 03:35 AM

on ‎2026-01-09 03:35 AM

Labels:
  • Exp-6 3rd Party Programs
  • Experior 6
325 Views

ABB RobotStudio

Downloading ABB RobotStudio   Go to http://new.abb.com/products/robotics/robotstudio/downloads Click Download Robot Studio x.xx.xx. Wait for the file to download.   Installing RobotStudio Right click on the desktop, select New and click Folder. Rename it to Robot_temp. Open the folder by double clicking it. Locate downloaded zip file and double click to open. Select all files and folders in the zip and drag across to the open Robot_temp folder. When the files have finished copying double click the file named Launch. If you get the User Account Control pop-up click YES. Select English (USA) from the drop down list and click OK. Click the Install Products button. Click the Robot Studio button. When the Welcome window opens click NEXT. Select I accept the terms in the license agreement. Click NEXT. Click ACCEPT. Leave destination folder as presented and click NEXT. Select Complete and click NEXT. Click INSTALL. When the install is complete click FINISH.   Installing RobotWare On the Install Products window which should still be open from previously, click the Robot Ware button. When the Welcome window opens click NEXT. Select I accept the terms in the license agreement. Click NEXT. Click ACCEPT. Leave destination folder as presented and click NEXT. Select Complete and click NEXT. Click INSTALL. When the install is complete click FINISH. Click Exit and Exit again to close the installer. Delete the Robot_temp directory.
View full article
Kasper.Vestrup Explorer
‎2026-01-09 03:28 AM

Labels:
  • Exp-6 3rd Party Programs
  • Experior 6
117 Views

Build a Controller

Step 1:   Make a C# project where the main class extends the Experior.Core.Controller or Experior.Core.Logic class. Experior.Core.Controller is for making controllers that interacts with a model running in the discrete event engine and Experior.Core.Logic is for controllers interacting with a model running in the physics engine.     Step 2:   To start Experior directly within Visual Studio set Start external program. Then you can insert break points in the controller code and debug the source code.     Step 3:   Make sure the output path is the same as Experior     Step 4:     Now build the model you want to control and link the compiled controller with the model.   You can add multiple controllers disable/enable a linked controller or unload an existing controller.  
View full article
Kasper.Vestrup Explorer
‎2026-01-15 05:59 AM

on ‎2026-01-15 05:59 AM

Labels:
  • Exp-6 Developer Guide
  • Experior 6
272 Views

Custom connection

It is possible to extend the functionality of Experior with custom communication protocols. This is done by creating your own plugin and extending Experior.Core.Communication.PLC.Connection.   In case your connection is TCP/IP based you can extend from Experior.Core.Communication.PLC.TCPIP.Connection.   Experior.Core.Communication.PLC.Connection In attached memcom communication plugin a custom connection is made that doesn’t use the network to communicate but instead uses a memory stream. This plugin can be used to quickly test your Input/Output driven components. You do this by connecting an input and an output through the same address of the memcom connection.   For example link the Pushed PLC Input symbol of a button to Byte 1 Bit 0 of the memcom connection and also connect the Lighting PLC output to Byte 1 Bit 0 of the memcom connection. When pressing the button the lamp will light up:   The custom connection uses a memory stream to achieve this because a memory stream has similar behavior as a regular network stream.   The source code contains some notes explaining how to achieve the same functionality without the memory stream (and just share the data buffer).   Whenever the user assigns an input/output from a component to a PLC connection then this input/output is assigned to a PLC Buffer (Experior.Core.Communication.PLC.Buffers.Input/Experior.Core.Communication.PLC.Buffers.Output). These buffers maintain an array of bytes and grows/shrinks whenever new inputs/outputs are added/removed.   So in the constructor of the connection we create the buffers and subscribe to the events that are triggered when their size should change or when new inputs/outputs are assigned to them.   It is possible to have multiple buffers in a connection. Therefore we distinguish between them in a connection using a unique key (string) the Source.   In the example plugin only 1 Input buffer and 1 Output buffer is used, each with a default Source name equal to “0”.   In the constructor we also restore the saved buffer in case it exists. public MemConnection(MemConnectionInfo info) : base(info) { input = new Core.Communication.PLC.Buffers.Input(); // first restore the saved outputbuffer if it exists if (info.outputs != null && info.outputs.Count > 0) { output = info.outputs[outslot]; } else output = new Core.Communication.PLC.Buffers.Output(); //give the input and output buffer a unique slot name input.Source = inpslot; output.Source = outslot; // subscribe to the different events to react upon data changes or to properly allocate the buffers output.BufferChanged += new Core.Communication.PLC.Buffers.Output.BufferChangedEvent(OutputDataUpdated); input.BufferChanged += new Core.Communication.PLC.Buffers.Input.BufferChangedEvent(InputDataUpdated); Experior.Core.Communication.PLC.Connection.Inputs.LengthChanged += new Inputs.LengthChangedEvent(Inputs_LengthChanged); Experior.Core.Communication.PLC.Connection.Outputs.LengthChanged += new Outputs.LengthChangedEvent(Outputs_LengthChanged); Experior.Core.Communication.PLC.Connection.Outputs.ConnectionedAssigned += new Outputs.OutputEvent(Outputs_ConnectionedAssigned); Experior.Core.Communication.PLC.Connection.Outputs.ConnectionedUnAssigned += new Outputs.OutputEvent(Outputs_ConnectionedUnAssigned); Experior.Core.Communication.PLC.Connection.Inputs.ConnectionedAssigned += new Inputs.InputEvent(Inputs_ConnectionedAssigned); Experior.Core.Communication.PLC.Connection.Inputs.ConnectionedUnAssigned += new Inputs.InputEvent(Inputs_ConnectionedUnAssigned); // add sources to the connection AddSource(input); AddSource(output); Experior.Core.Environment.Scene.Loaded += new Core.Environment.Scene.Event(Scene_Loaded); }   When the user assigns an Input/Output to the connection it triggers the Experior.Core.Communication.PLC.Connection.Inputs.ConnectionedAssigned and  Experior.Core.Communication.PLC.Connection.Outputs.ConnectionedAssigned events.   In the example we only use this to set the Source property of the Input/Output private void Inputs_ConnectionedAssigned(Input sender, Core.Communication.PLC.Connection connection) { if (this != connection) return; // here you can react upon the sender being added to this connection // in our case we just want to ensure the proper Source is set sender.Source = inpslot; }   Due to the nature of the example connection it is crucial that the Input and Output buffer have the same size so a big part of the source code is related to this.   When assigning Inputs/Outputs to a connection Experior verifies whether the buffer size should change and in those cases triggers the Experior.Core.Communication.PLC.Connection.Inputs.LengthChanged or Experior.Core.Communication.PLC.Connection.Outputs.LengthChanged events.   At all times you ask the minimum and maximum used byte of a input/output buffer by providing the connection and the Source of the buffer: int max = Experior.Core.Communication.PLC.Connection.Inputs.MaxSize(this, inpslot); int offset = Experior.Core.Communication.PLC.Connection.Inputs.MinSize(this, inpslot);   If the buffer is not large enough anymore you can allocate sufficient bytes: // allocate (max-offset) bytes for the input buffer starting from offset input.Allocate(max - offset, offset, Experior.Core.Communication.PLC.Buffers.Buffer.Units.SINT);   Note: Experior.Core.Communication.PLC.Buffers.Buffer.Units.INT is used to indicate that the given size should be measured in bytes. In case Experior.Core.Communication.PLC.Buffers.Buffer.Units.SINT is used the size will be measured in words of 16 bits.   After the allocation the input.Data property will be an array of bytes with the proper size. When the user tries to connect the connection the EstablishConnection() method is called. When he tries to disconnect the Disconnect() method is called. In our example we override both methods and set the proper state of the connection (Core.Communication.State). When establishing the connection we make sure that the Input/Output buffers are allocated with the same size. In case we use a memorystream we also start listening on the stream (similar as we would be on a networkstream).   When the states of the Input/Outputs are changed this is immediately reflected in changes of the corresponding Input/Output buffers of the associated connection and the BufferChanged events are triggered. In our example we write the changed buffer to the memorystream. A different thread reads the memory stream and when the byte array is received it calls the byte[] DataReceived(string source, byte[] data) method of the connection to indicate that the given source has received the given data. int l = memStream.Read(incoming, 0, incoming.Length); if (l > 0) { DataReceived(inpslot, incoming); }   This triggers the proper events on the changed Inputs/Outputs. In the example without the memorystream we simply share the Data of the buffer and directly call the DataReceived method.   Experior.Core.Communication.PLC.TCPIP.Connection This connection class inherits from Experior.Core.Communication.PLC.Connection and mainly adds some TCPIP specific properties like Port, IP address and distinction between server and client connection: string IP: This getter property is used to get / or set the IPv4 address used by this connection. For a server connection this is 127.0.0.1 (localhost).   int Port: This property is used to get or set the port number for the TCPIP connection.   bool Server: Getter property to indicate whether this connection is used as server or client.
View full article
Kasper.Vestrup Explorer
‎2026-01-15 05:57 AM

Labels:
  • Exp-6 Developer Guide
  • Experior 6
272 Views

Load class

Loads in Experior are used to model pallets, boxes, bags, that are transported by material handling equipment like conveyors and lifts.   The main namespace for loads is Experior.Core.Loads and the Experior.Core.Loads.Load contains some factory methods for creating loads with different load types.   The Experior.Core.Loads.Load class derives from the RigidPart class and hence inherits a lot of its interaction with the PhysX engine from it.   Note that there are some important differences related to loads depending on whether Experior is running in physics mode or discrete mode. In physics mode a load is considered a dynamic object (unless you disable the load or make it Kinematic). This implies that the position of the load and its orientation is determined by the underlying nVidia Physx engine who calculates this by applying all the forces/torques on it. In discrete mode no physics engine is used. There it is important to know that, unless a load is made undeletable, it will always be on a Route (Experior.Core.Routes.Route) or an Action Point (Experior.Core.Routes.ActionPoint). So, by default, if a load is no longer on a Route/Action Point then it will be deleted by the underlying engine.   Below we will illustrate a set of the main methods/properties of the Experior.Core.Loads.Load class.   Some methods/properties related to the interaction of the loads with the physics engine Sleep(): This is used in the physics mode to make the load unresponsive to the physics engine. The load will no longer respond to the forces applied to it. Note that you can WakeUp/Enable a load by clicking on it in the working area.   WakeUp(): This is used in the physics mode to “wakeup” a sleeping load and make it respond again to the physics engine. The load will again respond to the forces applied to it.   Vector3 CenterOfMassOffsetLocalPosition: When the physics engine applies a force to a load to make it moving it applies this force into the center of mass of a load. By default a loads density is equally distributed over the whole volume of the load and hence the center of mass of the load is also the geometrical center of the load. By providing the CenterOfMassOffsetLocalPosition you make it possible to move this center of mass and e.g. put the center of mass lower than the geometrical center to decrease the collapsing of a load.   NOTE: The value provided to this property is an absolute value. The CenterOfMassOffsetLocalPosition property provided in the property window of a feed is a relative one where 1 represents 100%.   Example and illustration. In the example below the CenterOfMassOffsetLocalPosition of the loads with dimensions (0.5f,0,5f,0.5f) is set to (0, -0.2f, 0) when the load enters a sensor: So the force will be applied 200mm below the geometrical center of the load. myLoad.CenterOfMassOffsetLocalPosition = new Vector3(0, -0.2f, 0);   You can clearly see that the force on the load is applied lower than before it entered the sensor.   bool Gravity: This indicates whether a load is subject to gravitational force. If you set it to false a load will not fall, but will remain subject to other forces like the force applied to it on a conveyor.   float Density: This represents the (uniform) density of the load. It is used to calculate the weight of the load ( Volume calculates as length times width times height multiplied with the Density).   bool Embedded: This indicates whether the load is embedded in another entity and hence whether it should be saved when saving the model. When the Embedded property is true the load is not saved. (In discrete mode loads are never saved).   bool Enabled: Setting Enabled to false is similar to calling Sleep() and setting Enabled to True is similar to calling WakeUp().   bool Kinematic: By default a load is a dynamic object by the PhysX engine which implies that its position and orientation will be determined by the physics engine by calculating all forces/torques applied to the load. By setting the Kinematic property to true, the load is made a kinematic object instead of a dynamic one. This implies that the load will no longer respond to the forces applied to it and the position and orientation of the load is controlled by the user. (Using the Methods/properties related to positioning of a load described below).   bool Rigid: Returns true when the load is a rigid body for the PhysX engine.   bool Sleeping : Returns true when the load has been “put to sleep” and is longer taken into account by the physics engine.   DeSelect(): Deselects the load.   Select(): Selects the load. The properties of the load will be shown in the properties window and the load will get the Select color.   HighLight(Color color): Highlights the load by changing the highlight color to the given color. This is only a temporary change. When the load is UnHighLighted is restores its original color (given by the Color property.   UnHighLight(). UnHighlights the load, as a result it will get the color back as defined by the Color property.   Color Color: Returns/sets the normal color of the load (when not selected or highlighted).   bool Selectable: Indicates whether a load can be selected by the user. If you set this property to False the user will not be able to select the load.   bool Selected: Returns True when the load is currently selected, False otherwise.   bool Transparent: Returns True when the color of the load is transparent.   Methods/properties related to deleting of a load Dispose(): Called when deleting the load   bool Deletable : Property to indicate whether the load can be deleted. If this property is set to False, trying to delete the load will fail (e.g. when resetting the model, which normally deletes all loads in the model)   bool UserDeletable: Property to indicate whether the user can delete the load (e.g.by selecting it and pressing the Delete button)   event DisposeEvent OnDisposed : This event is called when the load is completely disposed (deleted)   event DisposeEvent OnDisposing : This event is called beginning to dispose a load   Methods/properties related to grouping/deleting of a load Remark: In discrete mode the grouping/ungrouping of loads happens instantaneously and immediately after calling the Group/UnGroup methods the grouped load or ungrouped loads are available. Due to the nature of the physics engine this is postponed until the physics engine has finished its cycle of applying forces to loads. So in physics mode the grouped load is available when the OnGrouped event is raised.   Group(List<Load> loads): The current load will be grouped with all loads from the given list. They loads are grouped at their current relative position and the current load becomes the master load.   Group(Load load): The current load will be grouped with the given load. Both loads keep their relative position.   Group(Load load, Vector3 localposition): The given load will be grouped with the current load. It will be positioned given the relative position.    Group(List<Load> loads, List<Vector3> positions, List<Matrix> orientations): The given load is grouped with all loads from the given list of loads. Each load of the list is positioned according to the given relative position as provided in the positions list and with the orientation as described in the given orientations list of orientation matrices.   Group(Load load, Vector3 localposition, Matrix localorientation): The given load will be grouped with the current load. It will be positioned given the relative position and with the relative orientation as defined in the given orientation matrix.   Group(Load load, Vector3 localposition, float localyaw, float localpitch, float localroll): The given load will be grouped with the current load. It will be positioned given the relative position and with the relative orientation as defined by the relative Euler angles : localyaw, localpitch, localroll.   UnGroup(List<Load> loads): ungroups all loads from the given list of loads from the current load (masterload).   UnGroup(int loads): this will ungroup the given amount of loads from the current load. If the given number is larger then the total number of grouped loads it will ungroup all of them. If the number is smaller it will ungoup the given amount. The sequence of ungrouping is as follows: the last one grouped will be ungrouped first.   UnGroup(Load load): UnGroups the given load from the current load (masterload).   UnGroup(): UnGroups all loads that form the current load (masterload).   Collection Grouped: Returns the collection of loads that are grouped with the current load (the masterload). The Grouped collection allows to request the Length, Width, Height of the combined grouped load and you can iterate over all slave loads using the Items property of the Grouped property of the master load.   bool IsGrouped: Returns true for a load that has been grouped with a masterload. The materload itself will return false for this IsGrouped property.   event GroupedEvent OnGrouped: Is called when the load has been grouped. (See remark above concerning physics/discrete mode). The delegate has as argument the sender (masterload) and the result.   Below you find an example and screenshots of grouping: int createdloads=1;int totalnumber=10; Core.Resources.Mesh mesh=Common.Meshes.Get("Tote_Red"); Load ld1 = Load.Create(mesh, Length, Height, Width); ld1.Switch(linkedactionpoint); while (createdloads < totalnumber) { // create 4 more loads of given mesh and group them Load ld = Load.Create(mesh, Length, Height, Width); ld1.Group(ld,new Vector3(0,(Height-0.01f)*createdloads,0));//have totes slightly overlap // ld1.Group(ld,new Vector3(0,(Height+0.05f)*createdloads,0)) // create empty space between loads createdloads++; }   Above example results in the following stacks of totes being created depending whether we had loads overlapping or with empty space between them: Example of iterating over the grouped loads:   Experior.Core.Environment.Log.Write("Total dimensions are " + ld1.Grouped.Length + "; " + ld1.Grouped.Height + "; " + ld1.Grouped.Width); foreach (Load grl in ld1.Grouped.Items) { Experior.Core.Environment.Log.Write(" " + grl.Length + "; " + grl.Height + "; " + grl.Width); }   Methods/properties related to movement of a load in discrete mode MoveTo(string destination): This method will initiate a load traveling on its current route to the actionpoint with the name equal to the given destination. If the destination actionpoint is not reachable through routes connected to the current route then a message will be logged :  ‘Can’t continue: “destination” is unreachable (“current actionpoint name“)’   MoveTo(string source, string destination): This method will initiate a load traveling on its current route from the source actionpoint to the actionpoint with the name equal to the given destination.   Release(): This method will release a load that is stopped.   Release(float delay): This method will release a load that is stopped after the given delay has passed. The delay is given in seconds.   Stop(): This method will stop a load on its Route/ActionPoint. The load will wait there until it is released.   Switch(Route to): This method  will instantaneously take the load and put it at the start of the given route.   Switch(Route to, float distance): This method  will instantaneously take the load and put it at the given distance from the start of the given route.   Switch(Route to, bool keepGlobalOrientation): This method  will instantaneously take the load and put it at the start of the given route. When the keepGlobalOrientation argument is true than the load will keep its current global orientation (Yaw, Pitch, Roll), otherwise it will use the properties of the route.   Switch(Route to, float distance, bool keepGlobalOrientation): This method  will instantaneously take the load and put it at the given distance from the start of the given route. When the keepGlobalOrientation argument is true than the load will keep its current global orientation (Yaw, Pitch, Roll), otherwise it will use the properties of the route.   Switch(string actionpoint, bool keepGlobalOrientation): This method will put the load on the actionpoint with the given name.When the keepGlobalOrientation argument is true than the load will keep its current global orientation (Yaw, Pitch, Roll), otherwise it will use the properties of the actionpoint. If no actionpoint can be found with the given name the call is ignored.   Switch(ActionPoint ap, bool keepGlobalOrientation): this method will put the load on the given actionpoint. When the keepGlobalOrientation argument is true than the load will keep its current global orientation (Yaw, Pitch, Roll), otherwise it will use the properties of the actionpoint. In the illustrations below you can see the difference between switching a load (to AP6) with the keepGlobalOrientation argument true or false:       Switch(string actionpoint): This method will put the load on the actionpoint with the given name. If no actionpoint can be found with the given name the call is ignored.   Switch(ActionPoint ap, ActionPoint.Edges edge): This method will put the load on the actionpoint. The edge argument has 3 possible values ActionPoint.Edges.Leading, ActionPoint.Edges.Trailing and the defaultActionPoint.Edges.Center. If its value is Edges.Trailing then the load will be put on the actionpoint in such a way that the position of the actionpoint matches the trailing back of the load. If its value is Edges.Leading then the load will be put on the actionpoint in such a way that the position of the actionpoint matches the leading front of the load.   Note: This assumes that there is sufficient room on the route to do the switch, meaning that the center of the load should be on the route. Suppose you have an ActionPoint at the start of a route. In that case it is only possible to do the switch with edge ActionPoint.Edges.Center or ActionPoint.Edges.Trailing because using ActionPoint.Edges.Leading implies that the center of the load would not fit on the route.   Switch(ActionPoint ap): This method will put the load on the given actionpoint.   ActionPoint ActionPoint: This getter property returns the current actionpoint of the load or null if the load is on a route and not at an actionpoint.   string GoTo: This property allows to get of the name of the current final destination actionpoint. By setting this property to the name of an actionpoint the load will set it as its final destination and travel towards it.   Vector3 RouteOffset: Normally a load travels on the route with the center of the load moving over the route. By using the RouteOffset property you can chnage this and have the center of the load moving at the given relative position from the route.   Below you see an illustration of loads moving where load.RouteOffset = new Vector3(1.2f, 0.3f, 0f);   bool Stopped: This getter property returns True when the load is currently stopped, False otherwise.   float WaitingTime: Setting this property makes a load wait at its current position. The waiting time is provided in seconds. When this waiting time is elapsed the load will trigger the FinishedWaiting event and continue.   FinishedWaiting FinishedWaitingEvent: This event is triggered by a load when its WaitingTime has elapsed.   Methods/properties related to attaching a load to a RigidPart public bool IsAttached: This getter property returns true when the load is currently attached to a RigidPart and hence if following the movement of this part.   event AttachedEvent OnUnAttached: This event is triggered when the load gets unattached of the RigidPart it was attached to.   event AttachedEvent OnAttached: This event is triggered when the load gets attached to a RigidPart was attached to.   Attaching loads is done using one of the Attach methods of the Experior.Core.Parts.RigidPart class.   Custom Data object UserData: The developer can add custom data to a load by using this UserData property. E.g you can create you own TransportOrder class containing data from the WMS like PurchaseOrder,Customer, Source, Destination, DueDate,… and attach it to the load: myload.UserData = aTransportOrder;   You can inspect the data again by casting the UserData back to the class it was given: string customer = (myload.UserData as TransportOrder).Customer;   Methods/properties related to prositioning of a load float Yaw: This getter/setter property reflects the rotation angle (in radians) of the load around the Y-axis   float Pitch: This getter/setter property reflects the rotation angle (in radians) of the load around the X-axis   float Roll: This getter/setter property reflects the rotation angle (in radians) of the load around the Z-axis   Vector3 Position: This property returns the global 3 dimensional coordinates of the center of the load. In the physics mode the position is determined by the physics engine or its movement on tracks and in discrete mode by its movement on the routes. When the load is made Kinematic or Disabled then it makes sense to directly set the position of the load.   Matrix Orientation: This property returns or sets the orientation of the load as defined in the Microsoft.DirectX.Matrix structure.   Translate(Vector3 distance, float time): This will translate a stopped load over the given vector during the given time. After the given time the load remains at its position after the translation until it is released. In case the load continues moving on a route it will jump back to its position on the route. So note that the load should not be moving on a route when calling this translate method otherwise you get some strange wave movement during the given time where the load is trying to translate over the given vector but is pulled back by it having to move on the route.   Translate(Action action, Vector3 distance, float time): This method is similar to the Translate method above except that at the end of the translation of the load over the given vector distance the given action will be executed. The given System.Action is a delegate that you can use to pass a method as a parameter without explicitly declaring a custom delegate. The encapsulated method must correspond to the method signature that is defined by this delegate.This means that the encapsulated method must have no parameters and no return value.   In the example below a load is translated over 3 meter in the Y-direction in 2 seconds and at the end of the movement the load is switched to actionpoint  “AP10” and then released : currentload.Translate(()=>SwitchToAP10(), new Vector3(0, 3.0f, 0), 2f);   where: public void SwitchToAP10() { if(currentload != null) { currentload.Switch("AP10"); currentload.Release(); } }
View full article
Kasper.Vestrup Explorer
‎2026-01-15 05:55 AM

on ‎2026-01-15 05:55 AM

Labels:
  • Exp-6 Developer Guide
  • Experior 6
198 Views

ActionPoint class

Action Points are points on a Route where a load can stop and stay. They are used internally by Experior as vertices or nodes in the routing graph (where parts of the route between the action points are the edges).   They are implemented in Experior using the Experior.Core.Routes.ActionPoint class.   Main properties: string Name: Getter property for the name of this actionpoint. string APName: Gets or sets the name of this actionpoint. Route Parent: This getter property returns the route to which this actionpoint is added. Assembly:  This getter property returns the Assembly object to which this actionpoint belongs. Vector3 Position: This getter property returns the global position of this actionpoint. bool Routing: Gets or sets a value indicating whether this actionpoint should be included as node in the routing graph. bool Selectable: Gets or sets a value indicating whether this actionpoint is pickable by the user. bool Selected: Gets or sets a value indicating whether this actionpoint is selected. Experior.Core.Reports.Statistics.Statistic.Counter Statistic: This getter property returns the counter statistic linked to this actionpoint. ActionPoint.StoppingMode StopMode: This property gets or sets the stopping mode of this actionpoint. Possible values are: StoppingMode.None, StoppingMode.Stop, StoppingMode.Capacity, StoppingMode.StopMotor and only available in discrete event mode StoppingMode.Interval. ActionPoint.Edges Collision: This property gets/sets when an actionpoint triggers its Enter event. float Distance: This property gets/sets the distance of this actionpoint on its route measured from the start of the route. bool Active: This getter property returns whether this actionpoint is active (has load) or not. Load ActiveLoad: This getter property returns whether the current load on this actionpoint (or null in case the actionpoint is not active). string VirtualNode: This property gets/sets whether this actionpoint is a virtual node or not (default). This VirtualNode is used to join a group of nodes into one edge in the route graph. All actionpoints with the same VirtualNode value will behave as 1 node in the routing graph. static ReadOnlyDictionary<string, ActionPoint> Items: Static getter property that returns a read-only dictionary with all existing user actionpoints. Key in the dictionary is the name of the actionpoint while the value is the actual ActionPoint instance. Note: this dictionary only contains actionpoints that were added by the user, it does not contain the actionpoints that were created by code internally in assemblies. The developer should keep track of those.   Main events: event ActionPoint.EnterEvent Enter: This event is raised when a load enters this actionpoint. event ActionPoint.ReleasedEvent Released: This event is raised when a load leaves this actionpoint. It can be because the load was never stopped, or because the load is deleted or released or  switched to another ActionPoint or Route. event ActionPoint.MoveToEvent MoveTo: This event is raised when the MoveTo method is called on the load. event ActionPoint.RemovedEvent Removed: This event is raised when an actionpoint is deleted.   Example: public ActionPoint CreateActionPoint (int index) { ActionPoint ap = new ActionPoint(); ap.Edge = ActionPoint.Edges.Leading; ap.StopMode = ActionPoint.StoppingMode.Stop; ap.Name = index.ToString(); ap.Enter += new ActionPoint.EnterEvent(ap_Enter); ap.Released += new ActionPoint.ReleasedEvent(ap_Released); return ap; } void ap_Enter(ActionPoint ap, Load load) { // Example of gathering and logging some routing info // we will lo the previuous and next actionpoint and the distance to them float nextdistance; float prevdistance; ActionPoint next = Route.FindNextActionPoint(ap, out nextdistance); ActionPoint prev = Route.FindPreviousActionPoint(ap, out prevdistance); if (next != null) Experior.Core.Environment.Log.Write("Next ActionPoint of " + ap.Name + " is " + next.Name + " at distance " + nextdistance); else Experior.Core.Environment.Log.Write("No next ActionPoint found for " + ap.Name ); if (prev != null) Experior.Core.Environment.Log.Write("Previous ActionPoint of " + ap.Name + " is " + prev.Name + " at distance " + prevdistance); else Experior.Core.Environment.Log.Write("No previous ActionPoint found for " + ap.Name); // example of some diverting decision based on load info if (load.Identification == ap.Name) { //divert load to route Int16 idx=0; if (Int16.TryParse(ap.Name, out idx)) { load.Switch(divertroutes[idx].Route); load.Release(); } } else load.Release(); } void ap_Released(ActionPoint ap, Load load) { Experior.Core.Environment.Log.Write("ActionPoint " + ap.APName + " is released by load " + load.Identification); }   Main static methods static string GetValidName(string prefix): Actionpoints require a unique name. This method will create a unique name with the given prefix. static ActionPoint Get(string name): A factory method to create and return an actionpoint with the given name.If there was already an actionpoint with the given name then this existing one is returned. static ActionPoint Release(string name): This static method will release the actionpoint with the given name.
View full article
Kasper.Vestrup Explorer
‎2026-01-15 05:48 AM

Labels:
  • Exp-6 Developer Guide
  • Experior 6
114 Views

Extending the GUI with a Plugin

A plugin can be used to add custom functionality to Experior and you can also use it to extend the GUI by adding menu items and/or adding your own forms. A plugin is a dll that will be automatically loaded by Experior (provided the dll can be found in the installation directory of Experior). You can create your own plugin by creating a separate Visual Studio project where your plugin class derives from Experior.Core.Plugin.    Toolbar.Button To extend the GUI you can create a Button (Core.Environment.UI.Toolbar.Button) and add it to a toolbar.   In the example below a button is created and added to Model Toolbar in a Tab with name TestPlugin : Core.Environment.UI.Toolbar.Button IOButton = new Core.Environment.UI.Toolbar.Button("SensorOutputs", btnIOToggle_Click); IOButton.Tooltip = "Show outputs from sensors"; // add the button to the Model toolbar in a Tab with name "TestPlugin" Core.Environment.UI.Toolbar.Add(IOButton, "TestPlugin");   This will look as follows:   When the example SensorOutputs button is clicked it will trigger the associated btnIOToggle_Click method.   In this example this will update a custom form.   Experior.Core.Forms.Form Experior allows to add your own forms. You create your form similar to a normal System.Windows.Forms.Form.   However if you want to have a form that behaves similar to other Experior forms and is dockable, the created form should derive from Experior.Core.Forms.Form instead.   Also the FormType property has to be overridden. public override Core.Forms.Docking.DockContent.FormTypes FormType { get { return Core.Forms.Docking.DockContent.FormTypes.Permanent; } }   In attached example is a custom form that contains a datagrid will info of all Outputs for the sensors in your model. The form looks as follows when it is docked:   You can download the complete plugin attached to this article
View full article
Kasper.Vestrup Explorer
‎2026-01-15 05:47 AM

on ‎2026-01-15 05:47 AM

Labels:
  • Exp-6 Developer Guide
  • Experior 6
146 Views

Rigid Sensor Part

RigidSensorPart The class Experior.Core.Parts.Sensors.RigidSensorPart derives from the abstract class Experior.Core.Parts.RigidPart. RigidSensorPart objects are used in the PhysX environment to detect and manage collisions with RigidParts such as Loads and Assemblies. Since they rely on the collision detection of the PhysX engine they have no functionality in the discrete mode. RigidSensorParts are available in different shapes (Experior.Core.Parts.Sensors.Cube, Experior.Core.Parts.Sensors.Sphere, Experior.Core.Parts.Sensors.Cylinder) and with different functionality (Experior.Core.Parts.Sensors.LoadMagnet and Experior.Core.Parts.Sensors.EaterCube). All sensor assemblies of the Sensor catalog contain at least one RigidSensorPart.   An example of the creation and usage of a RigidSensorPart can be found here.   Events event EnterEvent Enter; This event is called when the sensorpart collides with a part it should detect according to its Collision property. The delegate it will call has two arguments, the activated sensorpart and the triggering object (can be cast to Load or Assembly).   event LeaveEvent Leave; This event is called when the sensorpart collides with a part it should detect according to its Collision property. The delegate it will call has two arguments, the activated sensorpart and the triggering object (can be cast to Load or Assembly).   Properties virtual bool Active This property returns true when the sensorpart collides with a part it should detect according to its Collision property, false otherwise.   Experior.Core.Environment.Collisions Collision The Collision property has 3 possible values : Core.Environment.Collisions.Both, Core.Environment.Collisions.Loads and Core.Environment.Collisions.Equipment. Core.Environment.Collisions.Both: in this case the sensorpart will detect loads as well as assemblies Core.Environment.Collisions.Loads: in this case the sensorpart only detects loads Core.Environment.Collisions.Equipment: in this case the sensorpart detects rigidparts of an assembly   List<Load> Loads This property returns the list of all loads that are currently colliding with the sensorpart.
View full article
Kasper.Vestrup Explorer
‎2026-01-15 05:43 AM

on ‎2026-01-15 05:43 AM

Labels:
  • Exp-6 Developer Guide
  • Experior 6
168 Views

Interaction with Excel files

Experior provides some methods to read data from an Excel file and to write data into an Excel file.   To do this you can use the Experior.Core.Data.Excel class with the following methods. public static List<List<string>> Read(string filename, string sheetname); public void Write(string filename, string sheetname, List<List<string>> records);   There is also the possibility to verify whether a worksheet exists in a an Excel file with a given name. public static bool Exists(string filename, string sheetname);   By using the classes Excel, ExcelWorkbook, ExcelWorkSheet, from the namespace Experior.Core.Data.OfficeOpenXml you can obtain even more direct control.   For example. string filePath = Experior.Core.Directories.Model + "\\Simulation_results_" + DateTime.Now.Day.ToString() + "_" + DateTime.Now.Month.ToString() + "_" + DateTime.Now.Year.ToString() + "_" + DateTime.Now.Hour.ToString() + "_" + DateTime.Now.Minute.ToString() + "_.xlsx"; // create a new Excel workbook with the given filename and add a Worksheeet named "Simulation results" Experior.Core.Data.OfficeOpenXml.Excel e = new Core.Data.OfficeOpenXml.Excel(new System.IO.FileInfo(filePath)); Experior.Core.Data.OfficeOpenXml.ExcelWorksheet worksheet = e.Workbook.Worksheets.Add("Simulation results"); // write the data into the cells of the worksheet worksheet.Cells[1, 1].Value = "Total occupation time conveyor system"; worksheet.Cells[1, 2].Value = swTotalOnConv.elapsed.ToString(); worksheet.Cells[2, 1].Value = "Waiting time drivers"; for (int i = 0; i < driverWaitingTime.Count; i++) { worksheet.Cells[3 + i, 1].Value = "Waiting time after pattern " + (i + 1).ToString(); worksheet.Cells[3 + i, 1].Value = driverWaitingTime[i].elapsed.ToString("c"); } // Add another worksheet named "Simulated Pattern" Experior.Core.Data.OfficeOpenXml.ExcelWorksheet worksheetPattern = e.Workbook.Worksheets.Add("Simulated pattern"); r = 1; c = 1; foreach (List<string> rows in SimulatedPatternSheet) { c = 1; foreach (string cell in rows) { worksheetPattern.Cells[r, c].Value = cell; c++; } r++; } //save the Excel workbook file e.Save();
View full article
Kasper.Vestrup Explorer
‎2026-01-15 05:42 AM

on ‎2026-01-15 05:42 AM

Labels:
  • Exp-6 Developer Guide
  • Experior 6
162 Views

RigidPart

The Experior.Core.Parts.RigidPart class is the base abstract class to encapsulate rigid bodies that are used by the NVIDIA PhysX engine.   Some important classes that derive from RigidPart are RigidSensorPart (used by sensors) and RigidLoadPart (used inside loads).   Methods & Properties related to attaching loads. The methods below are used to attach loads to a rigidpart and keep them at a given relative position and orientation to the RigidPart. For the physics engine the loads are no longer dynamic actors that are moved according to forces and torques that are applied to them, but instead the loads become kinematic objects after attaching them to a RigidPart. You can use these method e.g. to attach a load to a gripper of a robot or keep it on a fast moving shuttle.   Note: There is an important distinction between the different Attach methods related to the collision of the load with a sensor. This distinction is necessary due to a limitation of the PhysX engine. The physics engine does not give a notification if you use the program to change the position of a load that is in contact with a sensor. Therefore, in attach methods that change the position/orientation of the load the load is taken out of the sensors it was colliding with by the programming (generating the Leave event of the sensor to allow reacting upon this change).   Attach(Load load): This method will attach the given load to the current RigidPart.This implies that if the RigidPart moves/rotates that the attached load will move with it, keeping its relative position/orientation as when it was attached. When the load was colliding with a sensor the Leave event of the sensor is not called (see Note above).   Attach(List<Load> loads): This method will attach all loads from the given list to the current RigidPart. When the loads were colliding with a sensor the Leave event of the sensor is not called (see Note above).   Attach(Load load, Vector3 localposition): This method will attach the given load to the current RigidPart at the given relative localposition from the origin of the rigidpart.   Attach(Load load, Vector3 localposition, float localyaw, float localpitch, float localroll): This method will attach the given load to the current RigidPart at the given relative localposition from the origin of the rigidpart and with a relative orientation determined by the given localyaw, localpitch,localroll Euler angles.   Attach(Load load, Vector3 localposition, Matrix localorientation): This method will attach the given load to the current RigidPart at the given relative localposition from the origin of the rigidpart and with a relative orientation determined by the given orientation matrix localorientation.   Attach(List<Load> loads, List<Vector3> positions, List<Matrix> orientations): This method will attach all loads from the given list to the current RigidPart. The given positions list and given orientations list contains the releative position and relative orientation for the load with the same index in the loads list.   UnAttach(Load load): Unattach the given load from the current RigidPart and make it a dynamic actor again for the physics engine.   UnAttach(): Unattach all loads that are attached to the current RigidPart and make them dynamic actors again for the physics engine.   In the example below a load is attached to the sensor upon the Enter event. private void Entering(Core.Parts.Sensors.RigidSensorPart sensor, object trigger) { //already attached if (((Core.Loads.Load)trigger).IsAttached) return; //avoid that the load gets selected ((Core.Loads.Load)trigger).Selectable = false; //attach load at current relative position/orientation to the sensor part sensor.Attach((Core.Loads.Load)trigger); }   Methods & Properties related to PhysX interaction.   Actor Actor: This property sets/returns the instance of the Experior.PhysX.Actor class representing this RigidPart which is used inside the NVIDIA PhysX engine (NxActor class). Actors are the main objects in a physx simulation.   Experior.Core.Parts.Friction Friction: This property sets/returns the friction definition for this RigidPart as used by the physics engine. The Experior.Core.Parts.Friction class defines the static and the dynamic friction and has some predefined Friction configurations for the user’s convenience. These are Friction.Coefficients.Slippy, Friction.Coefficients.Sticky, Friction.Coefficients.Smooth & Friction.Coefficients.None. When you require more control over the static and dynamic friction values used for your RigidPart then you can provide custom values for the Static and Dynamic property of the Friction property when using Friction.Coefficients.Custom. var cube = new Experior.Core.Parts.Cube(System.Drawing.Color.DarkGray, info.length, info.height, info.width); cube.Friction.Coefficient = Friction.Coefficients.Slippy;   bool Kinematic: By setting the Kinematic property to true, the rigidpart is made a kinematic object instead of a dynamic one. This implies that the part will no longer respond to the forces applied to it and the position and orientation of the part is controlled by the user. When kinematic is false then the part is considered a dynamic object for the physics engine.   Methods & Properties related to relative positioning. bool Configured: This getter property returns true when the RigidPart is added to a parent object (e.g. assembly) and positioned using the LocalPosition, LocalYaw, properties.    float LocalYaw: This getter/setter property reflects the rotation angle (in radians) of the RigidPart around the Y-axis of its parent object.    float LocalPitch: This getter/setter property reflects the rotation angle (in radians) of the RigidPart around the X-axis of its parent object.    float LocalRoll: This getter/setter property reflects the rotation angle (in radians) of the RigidPart around the Z-axis of its parent object.    Matrix LocalOrientation: This property returns or sets the relative orientation of the RigidPart with respect to its parent object as defined in the Microsoft.DirectX.Matrix structure   Vector3 LocalPosition: This property returns or sets the relative 3 dimensional coordinates of the center of the RigidPart with respect to its parent object   Methods & Properties related to editing. bool Dragable: Tthis getter/setter property controls whether you can drag the RigidPart, e.g. The start and end fixpoints in the conveyor assemblies are Dragable by default to allow the user to change the length of the conveyor by dragging the fixpoints to another position. bool Locked: This getter/setter property allows to lock/unlock the RigidPart. When the part is locked it will change color to Colors.LOCKEDCOLOR (Yellow by default). bool Selectable: This getter/setter property allows to control whether the RigidPart can be selected (e.g. by clicking on it). IEntity Parent: This getter property returns the parent entity  form the RigidPart. If a RigidPart is added to an Assembly using then the Parent will return this Assembly.   Property related to rendering RenderingMode RenderOption: This getter/setter property is used to get/set how the RigidPart should be rendered. The following values are possible:   Primitive: The part will only be rendered when the Experior.Core.Environment.Scene.PresentationLevel of Experior is Core.Environment.Scene.PresentationLevels.Primitives   PrimitiveAndNormal: The part will only be rendered when the Experior.Core.Environment.Scene.PresentationLevel is Scene.PresentationLevels.Primitives or Scene.PresentationLevels.Normal or Scene.PresentationLevels.Detailed or only its wireframe when Scene.PresentationLevels.Wireframe.   Normal: The part will only be rendered when the Experior.Core.Environment.Scene.PresentationLevel is Scene.PresentationLevels.Normal, Scene.PresentationLevels.Detailed or only its wireframe when Scene.PresentationLevels.Wireframe   Transparent: The part will only be rendered transparently (you can see through it) when the Experior.Core.Environment.Scene.PresentationLevel is Scene.PresentationLevels.Normal, Scene.PresentationLevels.Detailed. Note: Transparency is only visible in Locked mode, in Edit mode the part is rendered nontransparent.   TransparentPrimitiveAndNormal: The part will only be rendered transparently (you can see through it) when the Experior.Core.Environment.Scene.PresentationLevel is Scene.PresentationLevels.Normal, Scene.PresentationLevels.Detailed and Scene.PresentationLevels.Primitives. Note: Transparency is only visible in Locked mode, in Edit mode the part is rendered nontransparent.
View full article
Kasper.Vestrup Explorer
‎2026-01-15 05:41 AM

on ‎2026-01-15 05:41 AM

Labels:
  • Exp-6 Developer Guide
  • Experior 6
86 Views

Open Office XML

The Experior.Core.Data library includes a tool for creating Office Open XML spreadsheets   The sample below shows how to create a work book with a sheet called “Data” FileInfo file = new FileInfo(@"c:\Test.xlsx"); if (file.Exists) { file.Delete(); // ensures we create a new workbook file= new FileInfo(@"c:\Test.xlsx"); } using (Experior.Core.Data.OfficeOpenXml.Excel excel = new Experior.Core.Data.OfficeOpenXml.Excel(newFile)) { Experior.Core.Data.OfficeOpenXml.ExcelWorksheet sheet = excel.Workbook.Worksheets.Add("Date"); sheet.Cells[1, 1].Value = "Data"; sheet.Cells[3, 1].Value = "1"; sheet.Cells[3, 2].Value = "2"; sheet.Cells[4, 1].Value = "3"; sheet.Cells[4, 2].Value = "4"; excel.Save(); }   Result:     Use the sheet:Cells[x,y].Style to set background color, font, border etc.
View full article
Kasper.Vestrup Explorer
‎2026-01-15 05:39 AM

on ‎2026-01-15 05:39 AM

Labels:
  • Exp-6 Developer Guide
  • Experior 6
182 Views

Internal communication

Experior provides an infrastructure for sending messages between objects.   In the Developer samples catalog an example of how to do this can be found.   The basic steps are; Register an object as a listener. Core.Communication.Internal.AddListener(object listener, RecieveMessage method)   For example. Core.Communication.Internal.AddListener(this, ReceiveMethod);   Where a method like this should be provided. void ReceiveMethod(object sender, object reciever, object message, bool broadcast)   2. Send a message to a known receiver. Core.Communication.Internal.SendMessage(object sender, object reciever, object message)   Broadcast a message to all listeners. Core.Communication.Internal.BroadcastMessage(object sender, object message)   Broadcast a message to all listeners of a specific type. Core.Communication.Internal.BroadcastMessage(object sender, Type recieverType, object message)   Broadcast a message to all listeners of a specific type (FullName). Core.Communication.Internal.BroadcastMessage(object sender, string recieverTypeFullName, object message)   3. When an object should stop listen or is disposed it should be removed. Core.Communication.Internal.RemoveListener(object listener)   Note: The specified delegate of the reciever is executed synchronously.
View full article
Kasper.Vestrup Explorer
‎2026-01-15 05:37 AM

on ‎2026-01-15 05:37 AM

Labels:
  • Exp-6 Developer Guide
  • Experior 6
125 Views

Dynamic Properties

You can add properties to assemblies at runtime.   To enable the feature the class has to use the attribute Experior.Core.Properties.DynamicObjectConverter.   Example: Adding properties two properties Properties.Add(newDynamicProperty { Name = "Value1", Type = typeof(int), Description = "custom property (integer)",Category = "Testing", Value = 1 }); Properties.Add(newDynamicProperty { Name = "Value2", Type = typeof(float), Description = "custom property (float)", Category = "Testing", Value = 10.0f });   By overriding the DynamicPropertyChanged method the object can handle the changes made to the properties added above public override void DynamicPropertyChanged(DynamicProperty property) { Log.Write(property.Name + " is changed to " + property.Value); }   See the sample DynamicProperties class in the Demo catalog for more information
View full article
Kasper.Vestrup Explorer
‎2026-01-15 05:36 AM

on ‎2026-01-15 05:36 AM

Labels:
  • Exp-6 Developer Guide
  • Experior 6
106 Views

Reports – create custom class

This example shows how to create a custom statistics class that shows up in the generated report.   To add public values to the Statistics form window in Experior set the Observe value to true.   public class TestStatistics : Core.Reports.Statistics.Statistic { public override string Title { get { return "Test Statistics"; } } private double example; [DisplayName("Example field")] public double Example { get { return example; } set { if (value != example) { example = value; NotifyPropertyChanged("Example field"); } } } }
View full article
Kasper.Vestrup Explorer
‎2026-01-15 05:35 AM

on ‎2026-01-15 05:35 AM

Labels:
  • Exp-6 Developer Guide
  • Experior 6
159 Views

Thread safe methods in Experior

To safely change properties and call methods in Experior be sure that you are running in the “Engine thread”. If the Property Experior.Core.Environment.InvokeRequried is false, then you are running in the “Engine thread”. Otherwise you need to invoke the method call.   Example code:   private void SomeMethod() { if (Experior.Core.Environment.InvokeRequired) { //Not running in Experior Engine thread Experior.Core.Environment.Invoke(SomeMethod); return; } //Put method code here. //Code is executed in Experior engine thread //and it is safe to call Experior methods. ... }
View full article
Kasper.Vestrup Explorer
‎2026-01-15 05:34 AM

on ‎2026-01-15 05:34 AM

Labels:
  • Exp-6 Developer Guide
  • Experior 6
128 Views

Route class

Routes are used in Experior to move loads following a track (linear, curve) without usage of the physics engine. Therefore routes are mainly used in discrete event mode. Routes are implemented in Experior using the abstract base class Experior.Core.Routes.Route. A straight route is implemented by the Experior.Core.Routes.Linear class, while a curved route is implemented by the Experior.Core.Routes.Curve class.   Routes may contain Action Points which typically represent destination points or decision points. By connecting routes Experior calculates the routing graph based on the nodes (action points) in the network. This routing graph can be used to calculate the shortest path to a new destination (Action Point ).   To incorporate routes in the working area and other components they are usually encapsulated in a TransportSection assembly. The TransportSection assemblies themselves are used as building blocks in the different Track assemblies.   A Route keeps track of the loads that are moving on it and of the Action Points it contains.   Note: In discrete event mode loads are always on a Route or on an Action Point. (Loads that are Deletable will be automatically deleted by Experior when they are not on a Route or Action Point).   Main properties: List ActionPoints: Getter property that returns all action points on this route.   LinkedList Loads: Getter property that returns all loads on this route.   Load First: Getter property returning the first load on this route.   Load Last: Getter property returning the last load on this route.   bool Bidirectional: Property that indicates whether Experior should consider this route as bidirectional or not when constructing the routing graph. Suppose the route between action points AP1 and AP2 is bidirectional than this means that the routing graph will have two edges between the vertices AP1 and AP2. In case the bidirectional property is false only 1 directed edge from AP1 to AP2 is available. Setting the bidirectional property has no impact on the actual movement of the loads: the developer still has to ensure that a load can move in opposite direction.   Motor Motor: Property that gets/sets the Motor used to control the movements of the loads on this Route. Changing the speed of the motor will change the speed by which loads move on its route and changing the speed sign will make the loads move in opposite direction.   Vector3 Start: Property that gets/sets the global position of the startpoint of the route.   Vector3 End: Property that gets/sets the global position of the endpoint of the route.   float Yaw: Getter property that returns the global Yaw of this route.   float Length: Property that gets/sets the total length of this route   bool Vertical: Property that gets or sets whether the route is vertical or not. This has an impact on how loads are positioned on the route.   bool Visible: Gets or sets a value indicating whether this Experior.Core.Routes.Route is visible.   float Yaw: Getter property that returns the global Yaw of this route   Main events: event Route.ArrivedEvent Arrived: This event is raised when a load arrives. This is not synchronized with the discrete event execution.   event Route.LoadAddedEvent LoadAdded: This event is raised when a load is added to the route.   event Route.LoadRemovedEvent LoadRemoved: This event is raised when a load is removed from the route.   static event Route.UpdatedEvent Updated: This event is raised when the routing graph is updated.   Main methods: void Add(Load load): This method will add the given load to the start of this Route.   void Add(Load load, float distance): This method will add the given load to this Route at the given distance from the start.   void Remove(Load load): This method will remove the given load from this Route.   ActionPoint InsertActionPoint(float distance): This method will create and return an actionpoint and position it at the given distance from the start of this route.   void RemoveActionPoint(ActionPoint ap): This method will remove the given actionpoint ap from this route.   void ClearLoads(): This method will remove all loads from this route.   Main static methods: static ActionPoint FindNextActionPoint(ActionPoint ap): Given an actionpoint ap this method will return the next axtionpoint on the route (returns null if no actionpoint is found).   static ActionPoint FindNextActionPoint(Route route): Given a Route route this static method will return the first actionpoint on that route.   static ActionPoint FindNextActionPoint(ActionPoint ap, out float distance): Given an actionpoint ap this static method will return the next actionpoint on the route (if any) and put the distance between the two actionpoints in the distance out parameter. static ActionPoint FindPreviousActionPoint(ActionPoint ap, out float distance): Given an actionpoint ap this static method will return the previous actionpoint on the route of ap and put the distance between the two actionpoints in the distance out parameter. If the route of ap does not have a previous actionpoint then the previous route is looked at to find the previous actionpoint.   static float ShortestDistanceToActionPoint(Load load, string destination): Given a load and the name of an actionpoint this static method will return shortest distance from the current position of the load to the actionpoint by following the shortest path on the linked routes. If no path can be found float.PositiveInfinity is returned and a warning is logged.   static float ShortestDistanceToActionPoint(string sourceAP, string destinationAP): Given the name of a source actionpoint  and the name of a destination actionpoint this static method will return shortest distance between the two actionpoints by following the shortest path on the linked routes. If no path can be found float.PositiveInfinity is returned and a warning is logged.   static void Update(): This static method will result in the updating of the routing graph. (This is also called when a user deletes or adds an actionpoint)   Example: float distance = Route.ShortestDistanceToActionPoint(load, "AP3"); if (float.IsInfinity(distance)) { Experior.Core.Environment.Log.Write("No path found from load " + load.Identification + " to actionpoint AP3"); } else { Experior.Core.Environment.Log.Write("Distance from load " + load.Identification + "to actionpoint AP3=" + distance); } distance = Route.ShortestDistanceToActionPoint("AP2", "AP3"); if (float.IsInfinity(distance)) { Experior.Core.Environment.Log.Write("No path found between AP2 and AP3"); } else { Experior.Core.Environment.Log.Write("Distance from AP2 to AP3=" + distance); }
View full article
Kasper.Vestrup Explorer
‎2026-01-15 01:02 AM

Labels:
  • Exp-6 Developer Guide
  • Experior 6
159 Views

[KNOWN ISSUE] Creating a custom catalog or plugin for Experior 6 in Visual Studio 2022

Please note that if you are creating a custom catalog or plugin for Experior 6 in Visual Studio 2022, you will get an error message when trying to compile the .dll. This is because Visual Studio 2022 will not be able to locate experior.build.dll. The reason it can’t locate the file, is because it is 32 bit and Visual Studio 2022 (or newer) is 64 bit.   You will be able to compile a catalog/plugin with previous versions of Visual Studio, for example 2019 is confirmed working with Experior 6.   Are you experiencing this issue and need help, feel free to contact us on email experior.support@se.com
View full article
Kasper.Vestrup Explorer
‎2026-01-15 12:34 AM

on ‎2026-01-15 12:34 AM

Labels:
  • Exp-6 Developer Guide
  • Experior 6
130 Views

Logging and Diagnostic messages

To provide diagnostic, debug or logging messages Experior provides several mechanisms.   Logging The Experior.Core.Environment.Log class provides the following static methods to write messages to the Log window. public static void Write(Exception exception); public static void Write(string message); public static void Write(Exception se, int id); public static void Write(string message, bool underline); public static void Write(string message, Color color); public static void Write(string message, LogFilter filter); public static void Write(string message, string hightlight); public static void Write(string message, bool underline, LogFilter filter); public static void Write(string message, Color color, LogFilter filter); public static void Write(string message, string hightlight, Color color); public static void Write(string message, string hightlight, LogFilter filter); public static void Write(string message, Color color, bool underline, LogFilter filter); public static void Write(string message, string hightlight, Color color, bool underline); public static void Write(string message, string hightlight, Color color, LogFilter filter); public static void Write(string message, string hightlight, Color color, bool underline, LogFilter filter);   The meaning of the arguments is straightforward; The message is the string that will be logged to the log window (and/or file depending on the properties set by the user in Experior). The highlight is part of the message that will be shown in bold. The color is the color in which the message will be shown. Underline, this boolean indicates whether or not the message will be underlined. The filter corresponds with the chosen filter by the user in the properties of the Log;   To illustrate, the following code Experior.Core.Environment.Log.Write("Created sensorpart assembly", "sensorpart", CadetBlue, true, Communication ); Experior.Core.Environment.Log.Write("Created sensorpart assembly", "sensorpart", Red, false, Action); will be shown as follows (when no filter is applied);     Debug log   Similar to the regular logging there is also the possibility to only log your message in case the debugging option is set in Experior.   In this case the Experior.Core.Environment.Log.Debug class is used with the public static void Write(string message) method.   Example: Experior.Core.Environment.Log.Debug.Write("This is an example debug message");   Diagnostic info   Experior also provides the possibility to print diagnostic messages to other areas than the logging window.   Therefore the class Experior.Core.Environment.Diagnostic contains the following static methods: public static void Message(string message); public static void Message(string message, Color color); public static void Message(string sender, string message); public static void Message(string message, Color color, Environment.DiagnosticAction action); public static void Message(string sender, string message, Color color); public static void Message(string message, Color color, Environment.DiagnosticAction action, Environment.Signs sign); public static void Message(string sender, string message, Color color, Environment.DiagnosticAction action);   By default the messages are shown in the status area underneath the working area.   The arguments are;   Message: The information that will be shown. Sender: This string appended with a : will be shown before the message. It is mainly used to provide the origin of the message e.g. the Assembly name. Environment.DiagnosticAction: This is an enum with the following possible values; ALARM in this case the message will also be shown in the alarm window of experior TEMPORARY in this case the message will only be shown for couple of seconds TEMPORARYANDLOG in this case the message will only be shown for couple of seconds but it will also be printed to the log window (where it will remain) STICKY in this case the message will remain visible in the status area until a new message is requested or until the message is removed or the Clear() method is called of the Diagnostic class REMOVE way to remove a STICKY diagnostic message NONE Environment.Signs: This is an enum to indicate what icon should be attached to the message in the status area.
View full article
Kasper.Vestrup Explorer
‎2026-01-15 12:31 AM

on ‎2026-01-15 12:31 AM

Labels:
  • Exp-6 Dev Environment
  • Exp-6 Developer Guide
  • Experior 6
115 Views

Serialization

Experior saves a model by serializing all necessary model entities (actually their corresponding Info objects) into specific xml files and compressing those into an experior file.   Loading a model works vice versa, the experior file is uncompressed and each xml file it contains is deserialized.   The serializing and deserializing can be done using System.Xml.Serialization.XmlSerializer.   However Experior also provides a utility class Experior.Core.Environment.Serialization to make this process simpler.   Example: // Log all serializable types List<Type> serializable = Experior.Core.Environment.SerializableTypes; Experior.Core.Environment.Log.Write("We found " + ser.Count + " serializable types."); foreach (var t in serializable) { Experior.Core.Environment.Log.Write(" : " + t.ToString()); } // create the test.xml file and serialize the Info object of this assembly into it Experior.Core.Environment.Serialization.Serialize("test.xml", this.Info); // load the test.xml file and deserialize into a AssemblyInfo object AssemblyInfo res = (AssemblyInfo)Experior.Core.Environment.Serialization.DeSerialize("test.xml", typeof(AssemblyInfo));
View full article
Kasper.Vestrup Explorer
‎2026-01-15 12:22 AM

on ‎2026-01-15 12:22 AM

Labels:
  • Exp-6 Dev Environment
  • Exp-6 Developer Guide
  • Experior 6
75 Views

Random

Experior.Core.Environment.Random   Experior.Core.Environment.Random can be used to get a pseudo random sequence of numbers.   Properties int Seed: This property allows to get/set the Seed of the standard pseudo random number generator used by Experior.   Changing the seed allows to get a new sequence of pseudo random numbers.   Experior.Core.Mathematics.Statistics.Generators.Pseudo.StandardGenerator Generator: This property allows to get/set the standard pseudo random number generator used by Experior.   The standard pseudo random number generator has methods to obtain random bytes, integers, doubles, booleans (See example below).   Methods void Reset(): This resets the number generator. After the reset the random number generator will generate the same sequence of numbers for the current seed.   int Random(): Returns a random integer.   int Random(int max): Returns a random integer less than the given max   int Random(int min, int max): Returns a random integer between the given min and less than the given max   Example: Below is an example of the usage of a random number generator of Experior: private void ExampleOfRandom(int seed) { // Example of usage of random number generator // Set the seed of the pseudo random number generator // By using the same seed you'll get the same sequence of pseudo random numbers which fullfills // the reproducablility requirement (e.g. when debugging) // Change the seed for each iteration of experiments Experior.Core.Environment.Random.Seed = seed; // get a pseudo random integer between -20 and less than 21 int randomint = Experior.Core.Environment.Random.Next(-20, +21); Experior.Core.Environment.Log.Debug.Write("Debug message " + attr1); Experior.Core.Environment.Random.Reset(); // randomint will be the same value as before because we have reset the random number generator randomint = Experior.Core.Environment.Random.Next(-20, +21); Experior.Core.Environment.Log.Debug.Write("Debug message after reset seed " + attr1); // reset the scene (this will also reset all assemblies and reset the standard random number generator) Experior.Core.Environment.Scene.Reset(); // randomint will be the same value as before because we have reset the scene randomint = Experior.Core.Environment.Random.Next(-20, +21); Experior.Core.Environment.Log.Debug.Write("Debug message after reset " + attr1); // You can get the standard pseudo random generator through Experior.Core.Environment.Random.Generator // this allows you to get random bytes, radom integers, random doubles, // get random double beteen 0.3 and less then 7.9 double randomnumber = Experior.Core.Environment.Random.Generator.NextDouble(0.3, 7.9); byte[] randombytes = new byte[10]; // fills the given byte array with random values Experior.Core.Environment.Random.Generator.NextBytes(randombytes); // get a random boolean value bool randombool = Experior.Core.Environment.Random.Generator.NextBoolean(); }
View full article
Kasper.Vestrup Explorer
‎2026-01-15 12:21 AM

on ‎2026-01-15 12:21 AM

Labels:
  • Exp-6 Dev Environment
  • Exp-6 Developer Guide
  • Experior 6
66 Views
  • « Previous
    • 1
    • 2
    • 3
    • 4
    • 5
  • Next »
To The Top!

Forums

  • APC UPS Data Center Backup Solutions
  • EcoStruxure IT
  • EcoStruxure Geo SCADA Expert
  • Metering & Power Quality
  • Schneider Electric Wiser

Knowledge Center

Events & webinars

Ideas

Blogs

Get Started

  • Ask the Community
  • Community Guidelines
  • Community User Guide
  • How-To & Best Practice
  • Experts Leaderboard
  • Contact Support

    Ask our Experts

    Have a question related to our products, solutions or services? Get quick support on community Forums

    Email Us

    For Community platform-related support, please email us

Subscribing is a smart move!
You can subscribe to this board after you log in or create your free account.
Forum-Icon

Create your free account or log in to subscribe to the board - and gain access to more than 10,000+ support articles along with insights from experts and peers.

Register today for FREE

Register Now

Already have an account? Login

Terms & Conditions Privacy Notice Change your Cookie Settings © 2026 Schneider Electric

Welcome!

Welcome to your new personalized space.

of

Explore