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: Exp-7 Developer
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: "exp-7 developer"

View in: "Digital Twin" | Community

16 Posts | First Used: 2026-01-05

Digital Twin

Sort by:
Date
  • Date
  • Views
  • Likes
Options
  • Knowledge Base Article Dashboard
  • Subscribe
  • Bookmark
  • Invite a Friend
Label: "Exp-7 Developer" Show all articles

Advanced Physics Dynamics

Introduction The current implementation of the Physics Engine in Experior 7 presents difficulties in accurately simulating the dynamics of loads under certain scenarios commonly found in conveying system applications. This may partially or entirely alter the results of simulation and emulation models, requiring workarounds to overcome these issues.   To address these challenges, a new implementation called Advanced Dynamics has been developed to provide a generic solution that covers a broad spectrum of complex dynamics scenarios presented in case conveying and pallet conveying systems, with respect to the motion of loads produced by forces exerted by conveyors. However, it is not within the scope of this new implementation to provide a solution that represents a 1:1 version of real physics (e.g., material deformation), considering the computational limitations of real-time simulations.   Development The following section describes the main points that have been reworked to significantly impact the overall physics engine.   Load transition Problem The displacement of the load is affected, either partially or totally, by the collision between the load and the belt that occurs during the transition in merge and divert sections. Flawless transitions depend on the geometry and dimensions of the load. Load orientation (Yaw) is affected during the transition, regardless of whether the configuration is straight-straight or straight-curve sections. Merge configuration old    Orthogonal configuration old   Cylinder transition old   Small Box transition old   Curve-Straight configuration old   Solution Whenever there is a collision between dynamic actors (i.e. loads) and static actors (i.e. belts), PhysX generates contact points that the contact solver uses to determine the velocity and position of the load. However, before the contact solver is applied, the properties of these contact points, such as the vector orientation, are modified to ensure a smooth transition, regardless of the geometry or dimensions of the load. The primary purpose of contact modification is to enable seamless transitions between conveyors, without requiring the use of ramps.   Orthogonal Configuration    Parallel Configuration   Inline-Decline   Contact Points Problem   Loads can exhibit unrealistic behaviors in certain scenarios where they come into contact with more than one surface simultaneously. This is because only the greatest velocity is applied. The current implementation lacks the capability to retrieve information about the contact points generated by the surfaces and the load.   Parallel Configuration old   Orthogonal Configuration old   Solution   PhysX filter allows retrieval of information related to contact points generated by collisions between dynamic and static actors. This makes possible to develop proper mathematics which considers the distance between the load’s center of mass and the position of each contact point to apply forces and torques correctly.   Parallel Configuration New    Orthogonal Configuration New   Friction Specifically, this refers to the friction force a conveyor surface applies to a load. Experior 7 calculates this friction force when the speed of the surface motor on a belt is different from zero. When the speed of the surface is zero, the PhysX engine from Nvidia will take over these calculations. Note: Patch and Two directional refer to the two friction modes from Nvidia PhysX supported in Experior 7. This only affects the friction force when it is being handled by the PhysX engine (i.e.: surface speed is zero). The key differences are: Two-directional combines the load and the surface friction coefficients for the force calculations, whereas Patch gives priority to the surface friction coefficients. According to the Nvidia PhysX documentation, Patch mode has better performance. Two-directional mode is more realistic, especially with static friction, as patch mode has unrealistically strong static friction. This behavior is most noticeable when a load is touching surfaces with non-zero velocity and zero velocity simultaneously. In Experior 7, the friction mode can be set through the command line arguments (patch is the default value). Experior 6 only supports the Two-directional mode.   Problem   The friction force calculations made by Experior 7 and the PhysX engine are inconsistent. An acceleration-deacceleration test showed this, where a load starts from rest on a conveyor. Afterward, the motor is turned on with a speed of 1.5 m/s and then is turned off (motor acceleration and deceleration are disabled). The following images show the load speed plotted against time. As the same physical phenomenon (dynamic and static friction) is responsible for the acceleration and deceleration of the load, we would expect the plotted curves to have a symmetrical behaviour. However, It is noticeable that the load behaves differently when accelerating and decelerating. This shows the inconsistencies between the force calculated by Experior 7 and the PhysX engine.   Solution   According to the Nvidia PhysX documentation, the friction force is calculated using the Coulomb friction model. To make the calculations from Experior 7 more consistent, we are now calculating friction force based on the Coulomb friction model. The following images show the results of the acceleration-deceleration test with the new friction calculations. Due to the symmetry in the curves, we can see that the friction force of the conveyors is now consistent when the motors are on and off.   Load Trajectory Problem   When the surface in contact uses sticky friction, Experior directly defines the load’s LinearVelocity property. However, this approach is inconsistent with PhysX, which computes all the forces exerted on a dynamic actor to determine its velocity and position. Furthermore, when the friction is not sticky, forces and torques are applied without regard of the surface’s orientation.   Incline-Decline old   Curve configuration old   Solution   Forces and torques are calculated based on the alignment of the surface and the information extracted from the contact points. During transitions from straight to curve and from curve to straight, forces and torques are applied independently to each surface. This is determined by the position of the center of the load. Remove the ramps from the conveyors. Incline-Decline new   Curve Configuration new   Stacks Problem The current physics engine configuration does not allow for stable stacking or displacement due to the default collision detection system (Permanent Contact Manifold). PCM is a distance-based collision detection system that can generate fewer contacts, potentially reducing the stability of tall stacks when simulating with insufficient solver iterations. Stacks old   Solver iterations refer to the minimum number of position and velocity iterations used by the contact solver behind the scenes to determine the velocity and position of a load.    Solution The physics engine configuration now includes a new feature called “Average Point”. This feature generates additional contacts per manifold to represent the average point in a manifold. It can stabilize a stacking effect when only a small number of solver iterations are used. The following videos demonstrate the difference when increasing the number of solver iterations from P:4,V:1 to P:20,V:5. Stacks 4 1 new   Stacks 20 5 new   Thanks to the new implementation, stacking and destacking processes no longer require additional functionalities or logic to achieve the correct behavior of the stack (e.g., the use of Group() and Ungroup() from the Load class). However, limitations from PhysX are still present when using a stack with a significant number of loads. The next two videos demonstrate the stacking and destacking processes, where the sensor between the forks only attaches to the load making contact.   Stacking new   Destacking new     Sleep Threshold Problem The PhysX solver continues to execute even when the load is not moving, resulting in unnecessary consumption of computational resources. In the video, it is evident that the arrow of each load which represents the linear velocity, keeps moving around continuously, even though the loads are completely static. Sleep Old   Solution Each dynamic actor contains a property called SleepThreshold, which sets the mass-normalized kinetic energy threshold below which an actor may go to sleep. Once an actor goes to sleep, PhysX will not report or notify it.   If a load on top of a conveyor is in a sleeping state, it will automatically awaken once the motor starts (CurrentSpeed != 0f). This is due to the notification from the motor to the PhysX engine through the method BeginStart(). However, it will take one more frame for the physics engine to move the load. It’s important to note that any motor developed using inheritance from the Electric class must use the method BeginStart when starting the motor.   Sleep new   Sleep Conveyor new   Risks / Side Effects To address the issues that were disclosed, it was necessary to implement new functionalities, which may have some unintended consequences. The following section outlines the potential risks associated with each of the proposed solutions. Performance     Performance decreased 18% Processor: i7-9750H CPU 2.60 GHz Ram: 16 GB Nvidia GeForce RTX 2070   A test was conducted to compare the performance of Advanced Dynamics with the current implementation, Classic Dynamics, which was considered a benchmark due to its efficiency. As shown in the image, Classic Dynamics is capable of handling 850 loads without exceeding the 16 millisecond threshold (the threshold is determined by the cycle task frequency of 60Hz), whereas Advanced Dynamics surpasses it. Based on the results of this specific test, Experior’s performance decreases by approximately 18%. It is important to note that performance can vary due to hardware specifications, as well as the size of the model and assemblies contained within it.   Precision to represent reality In some specific cases, uncertainties about the real-life dynamics of the load may arise due to the broad spectrum of complex scenarios and the lack of physical facilities to test them. Therefore, we are open to discussing and improving based on your feedback.   Although the mathematics defining the dynamics of the load and configuration of the PhysX engine have been reworked, computational limitations still persist due to the contact solver capacity. This is particularly evident when implementing tall stacks (more than 15 loads) or handling loads with very small dimensions. This limitations are expected to improve after updating the PhysX engine version in the near future. Dynamic 1    Dynamic 2   False Expectations Users should not expect to obtain the same results when using Advanced Dynamics as when using Classic Dynamics with regards to load dynamics, particularly when modifying the friction coefficients. The old implementation was developed in a specific way to overcome problems resulting from the lack of information and default configuration of PhysX, such as very high and low coefficient values. As shown in the following video, using the smooth friction type from Classic Dynamics will not produce the same results in Advanced Dynamics.   Expectations   Implementation To fully take advantage of the advanced dynamics, it is strongly suggested to remove the ramps of the belts used in your catalog. A new query property Experior.Core.Environment.Engine.AdvanceDynamics has been introduced, so that developers can handle the proper removal of ramps based on the physics engine dynamics. Users have the option to select the Physics engine dynamics type through the CLA (Command Line Argument) -physicsenginedynamics “advanced”. By default, Experior 7 will use “classic”. This parameter can be set from the cmd or the shortcut configuration as the following images show.     MinPositionIterations and MinVelocityIterations properties have been added to the class Load.  Global SleepThreshold property set automatically to 5e-5 if advanced dynamics is used. Nevertheless, the property SleepThreshold is available from the class Load. Visualization of contact points are displayed in debug visualization mode when using advanced dynamics. New friction coefficient values have been defined. Experior will automatically set the appropriate friction coefficient based on the selected physics engine dynamics. The following image displays the friction coefficient values defined for advanced dynamics mode.
View full article
Kasper.Vestrup Explorer
‎2026-01-30 05:38 AM

on ‎2026-01-30 05:38 AM

Labels:
  • Exp-7 Developer
  • Experior 7
370 Views

RigidPart – Overview

The RigidPart class serves as the base class definition for Part models in Experior to build on top of. RigidPart further splits into Static (See article “Static : RigidPart”) for scenery/Assembly models and Dynamic (See article “Dynamic : RigidPart” ) related to Loads, both which derive from RigidPart. Static models refer to models that describe the environment in an Experior model. Dynamic refers to load models that needs to be moved by the Experior model.   Most importantly, models deriving from Static are not affected by gravity, whereas models deriving from Dynamic are affected by gravity force. Additionally, Dynamic models have inertial physics, meaning mass as well as linear/angular movement in accordance with NVIDIA’s PhysX engine implementations (PhysX Documentation).   The figure below illustrates the class overview, with visuals examples of imported models deriving from both classes. Experior's RigidPart base class, which Dynamic and Static classes derives from. Dynamic is the base class for handling Load models. Static is the base class for handling 3D models related to Parts.   Methods and Properties   The RigidPart class does not implement physics related properties and methods as it did in earlier Experior versions. Those definitions have been moved to Static and Dynamic, where those classes implement how they interact with the engine in different ways. Only exception is the Friction coefficient property.   Therefore, RigidPart takes care of defining the following, many of which are open for extension:   Name and Identification Transformations Positioning – Global and Local Local Rotation Local Orientation Coloring – Base color, Selected color Visibility in the scene Disposal handling Selection/Deselection Enabling/Disabling Parenting objects Interaction Mouse click handling Mouse dragging handling Keyboard hotkey click handling Friction coefficient – sets friction force of a Part, defining how easily objects “glides” across its surface.
View full article
Kasper.Vestrup Explorer
‎2026-01-05 06:06 AM

Labels:
  • Exp-7 Developer
  • Experior 7
112 Views

Importing and Reading Excel files

This article outlines how to import and read Excel files contents using a custom plugin.   1. First, create a new project using the Plugin template available HERE. If you already have a plugin project, skip this step.   2. It is necessary to install two NuGet packages. Therefore, in the solution explorer of visual studio, use right click on the Dependencies section, and select the option Manage NuGet Packages. Browse and install the following NuGet packages     3. Opening and reading a file with the recently added library can be performed as follows:   /// <summary> /// Class <c>Excel</c> provides methods to read the content of an Excel file. /// </summary> internal static class Reader { /// <summary> /// Opens and reads the content of an Excel file /// </summary> /// <param name="filePath"></param> /// <returns>A collection of Content type which contains the content of each Sheet</returns> public static List<Content> Open(string filePath) { try { using (var stream = File.Open(filePath, FileMode.Open, FileAccess.Read)) { // Auto-detect format, supports: // - Binary Excel files (2.0-2003 format; *.xls) // - OpenXml Excel files (2007 format; *.xlsx, *.xlsb) DataSet result; using (var reader = ExcelReaderFactory.CreateReader(stream)) { result = reader.AsDataSet(); } var content = new List<Content>(); foreach (var table in result.Tables) { var tableInfo = new List<List<string>>(); if (!(table is DataTable sheet)) { continue; } for (var i = 0; i <= sheet.Rows.Count - 1; i++) { var rowInfo = new List<string>(); for (var j = 0; j <= sheet.Columns.Count - 1; j++) { var value = sheet.Rows[i][j] == null ? string.Empty : sheet.Rows[i][j]; rowInfo.Add(value.ToString()); } tableInfo.Add(rowInfo); } content.Add(new Content(sheet.TableName, tableInfo)); } return content; } } catch (Exception e) { Log.Write($"An error has occured during the reading process of the Excel file {filePath}. Please, see Debug.log"); Log.Debug.Write(e); return null; } }   The Excel file’s content is returned through the variable “content,” which provides a list of items. Each item corresponds to a sheet and its content/data. Notably, the content read from the Excel file is of type string. Developers must perform any necessary type conversions for specific data types.   You can download the attached plugin project, which contains a blue print to implement Excel reading files logic.
View full article
Kasper.Vestrup Explorer
‎2026-01-05 05:51 AM

Labels:
  • Exp-7 Developer
  • Experior 7
331 Views

Load Class

Load type "Default" representing an xcelgo logo box (1m, 1m, 1m)   Loads in Experior means models that represent items to be transported by material handling equipment such as conveyors, lifts or cranes.   The Load class takes care of definitions for both the Physics Engine and Discrete Events Engine, where there are important differences to take note of. In Physics mode, a Load is considered a dynamic object (Kinematic = false). This implies that the Load’s position and orientation is determined by the underlying NVIDIA PhysX engine, which experior’s physics engine is built on. The PhysX engine applies forces/torques on the Load to achieve positioning/rotation/orientations.   In Discrete Events Mode, the physics engine is not used (Kinematic = true). Here it is instead important to note that, unless a given Load is made undeletable, the Load will always be on a Route or an Action Point. When a Load is no longer on either of these, it is deleted from the environment by the underlying engine. In Discrete Events mode, Loads are not saved when an Experior Model is saved either, which they are in physics mode.   Built in Load types in Experior are implemented by a Load type class that inherits from Dynamic, which defines the physics actor implemented by a given Load type. Some of the physics related concepts implemented in Dynamic are also defined in the Load class, hence why their documentation will overlap.   Concepts Implemented in the Load Class A comprehensively detailed view of available methods and properties implemented can be found in the API Load Class documentation.   Generally Shared Implementation   Concepts that apply to all Loads, regardless of engine Experior is running in. Load Identification – Such as “Barcode” strings. Transformations Positioning (x = Length, y = Height, z = Width) Orientation Rotation (Yaw, Pitch, Roll) Load Coloring For selected/unselected state and highlighting when an action point is reached for instance. Selectable – Whether the Load is selectable by mouse clicks. Deletable Disposal Handling Visibility Grouping Defines whether a given Load is part of a group of Loads. Note: In Discrete Events mode, grouping/ungrouping Loads happen instantaneously, whereas the Physics engine requires finishing its current cycle of applying forces to Loads before grouping/ungrouping can occur. Attachment Whether the Load is attached to another RigidPart and therefore follows that RigidPart’s movement. Report Boolean to decide if the Load should be counted in the Statistics counter/window in Experior. Parenting Takes care of correctly setting parent/child hierarchies when multiple Loads are part of a grouping or attached to other RigidParts. User Data Users can add customized data to a Load, which for instance could represent data from a WMS such as PurchaseOrder, Customer Source, Destination, DueDate..etc. and attach it to the Load. Mouse/Keyboard Interaction methods open for extension Keyboard: KeyUp() and KeyDown() methods. Mouse: DoubleClick() method. Kinematic A Kinematic = true actor will act as if it has infinite mass, which means it can push regular non-kinematic dynamic actors away, but cannot be pushed back itself. Secondly, if movement is intended for the Part, the programmer must define the actor’s movement each time step, which can be useful if it is desirable that the object should follow a specific pre-defined path.  (Physics) Kinematic = false. (Discrete Events) Kinematic = true.    Physics Related Implementation   Friction coefficient – sets friction force of a Load, defining how easily it “glides” across a surface. Rigid – Matters in defining how the actor behaves when collisions occur. Also defines how precise the collision should be (as in how closely collision detection point matches point on the mesh) – this is also a question of performance, where rigid body shape complexity increases performance cost. Rigid body shape – has the following options: None Box (Default) Rounded Dice Sphere Convex Linear/Angular Dampening Linear/Angular Velocity Center of Mass Position When the physics engine applies a force to a Load to make it move, the force is applied into its center of mass. By default, a Load’s density is equally distributed over the whole volume of the Load and hence the center of mass of the Load is also its geometrical center. By providing the CenterOfMassOffsetLocalPosition, it is possible to move this center of mass and potentially place 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 feeder is a normalised value, where 0:0:0 is center of the Load and 0:1:0 would be at the top-center position.  Collision Detection (true/false) Default: true Density – used in calculating Load’s weight, which in Experior is Density * Volume. AddForce()/AddTorque() Sleep/Wake – Physics concept of enable/disable. Setting a Load as “Sleeping”, means it will no longer responds to physical forces applied to it, until it is enabled/woken up again.   Discrete Events Related Implementation   Loads move through an Experior model differently in Discrete Events mode compared to Physics, as described in the articles regarding differences between discrete events and physics and Action Points. The Load class contains implementations for handling moving Loads to another Action Point or Route, defining what should happen in the event of a Load reaching an Action Point, advancing simulated time and returning information regarding the events that occur for the Loads such as total distance traveled.   Examples of concepts implemented: Stopping/Releasing Loads on Action Points, meaning stopping and moving Loads when its a given Load’s time to step forward in time. Moving Loads directly to a specified Action Point Switching Loads to another Route or Action point with a variety of overloaded methods that handle different parameters, such as distance from start of the route, rotation and more. Distance (or “space”) a given load occupies on a route Getting the next event time, used by the Discrete Events engine to correctly determine the order in which to process the incoming events. RouteOffset can be set on a load, to offset it from the center line on a conveyor.  
View full article
Kasper.Vestrup Explorer
‎2026-01-05 05:58 AM

Labels:
  • Exp-7 Developer
  • Experior 7
208 Views

Script Window

The script window in Experior allows you to call the Experior API, within an instance of Experior.   It allows you to interact with Experior and e.g. stimulate the active model. An example usecase could be running a model without being connected to a physical PLC.   The shown model below has been set up through scripting, so that the first motor starts when a load activates the first sensor and a new load will be created when the load activates the second sensor. Gif is also attached as mp4 in this article.     The script window could contain following code: using System; using System.Numerics; using System.Windows.Media; using System.Linq; using Experior; using Experior.Core; using Experior.Interfaces; using Experior.Core.Loads; using Experior.Core.Routes; using Experior.Core.Communication.PLC; public partial class Main { public void On(object trigger, string symbol) { if (symbol == "SENSOR1") { Experior.Core.Motors.Motor.Get("MOTOR1").Start(); } if (symbol == "SENSOR2") { Experior.Core.Assemblies.Assembly.Get("FEEDER1").Activate(); } } public void Off(object trigger, string symbol) { } }   For pre-defined script helper methods, you can right-click within the script window to insert the following methods:   Initialize On (default inserted) Off (default inserted) Motor Started Motor Stopped Input Changed Output Changed Message Received Telegram Received Step Activation Arrived Enter (Action Point/Sensor) Leave (Action Point/Sensor) Elapsed Reset Pause Continue Dispose   Dispose:   When you press the “Compile” button in the top left of the script window the Dispose() method is called. You can use this method to unsubscribe from events and perform other clean-up actions.   Note: Since the Dispose() method is called before the compilation happens, it will not be the current version of the Dispose method as that one has not been compiled yet. It will be the Dispose method from the last time you compiled.   To make sure the Dispose method that is called matches the most recent implementation, it is best to compile every time you make changes to your Dispose method.   Initialize:   The Initialize method, runs as soon as compiling the script finishes.   On:   This method is called when:   Receiving input through a connection and the incoming data is of the type bool and its value is “True”. When a button is pressed in the “Control Panel” window. When a sensor is activated by a load.   Off: Same as On, but the value is “False”.   Motor Started: Is called when a motor is started.   Motor Stopped: Is called when a motor is stopped.   Input Changed: This is called when the input changes.   Output Changed: This is called when the output changes.   Message Received: Called when a message is received.   Telegram Received: Called when a telegram is received.   Step: Called at every frame update.   Activation: Called when an SRM is created.   Arrived: Called when a load arrives at a node.   Enter: Called when a load enters a sensor or actionpoint.   Leave: Called when a load leaves a sensor or actionpoint.   Elapsed: Called when a timer elapses.   Reset: Called when the scene is being reset.   Pause: Called when the scene or model gets paused.   Continue: Called when the scene or model gets unpaused.
View full article
Kasper.Vestrup Explorer
‎2026-01-05 06:03 AM

Labels:
  • Exp-7 Developer
  • Experior 7
228 Views

Experior 7 - API

Due to our move from a self hosted webpage to the following community structure, the API documentation is now available as static html files you need to download attached file, unzip and then open any one of the html files in the folder.
View full article
Kasper.Vestrup Explorer
‎2026-01-15 06:21 AM

on ‎2026-01-15 06:21 AM

Labels:
  • Exp-7 Developer
  • Experior 7
414 Views

InfluxDBLogTarget

TECH TIP  😺🖥   Someone asked; “Is it possible to get the logs generated by Experior inside my VM or docker container, stored somewhere in a common accessible location – and can you perhaps make them easily searchable/filtered etc. ? ”.   Ok…first question; Getting hold of the logs ?;   Experior already provides an easy way to get a hold of the logs (or rather receive the logs as they are generated) via the API. Simply create an Experior plugin where you implement interface ‘Experior.Interfaces.ILogTarget’ and subscribe in to our Experior.Core.Environment.Log.Subscribe(ILogTarget) and you have a class that will receive all logs from Experior. public class InfluxDBLogTarget : Experior.Interfaces.ILogTarget { public string LoggerId { get; } = "MyId"; public string LoggerLocation { get; } = "MyLocation"; public bool Enabled { get; set; } public bool Active { get; } public void Open() { Experior.Core.Environment.Log.Subscribe(this); } public void Close() { Experior.Core.Environment.Log.Unsubscribe(this); } public void Log(ILog log) { //todo - log to destination } public void Log(List<ILog> logs) { //todo - log to destination } public void ClearLog() { //todo - clear destination if supported } public void Dispose() { Close(); } }   So far so good…   Destination ?: You have a ton of options here, since Experior doesn’t restrict you using any of the thousands of 3rd party software, nugets, libraries or custom code (build from scratch in F# if that’s your preferred flavor). For this example we decided to try out the interesting InfluxDb (https://www.influxdata.com/).   InfluxDb is a high-performance time series database, that comes with several ways of ingesting data (getting data into it).   After a few minutes of google time, InfluxDb was installed on our windows box using docker (www.docker.com).   For getting data into the Influx database, there seems to be a couple of ways to go about this. Direct web API, C# client, or using a Telegraf plugin.   We love nugets and luckily there’s a nuget for it (InfluxDb.Client – https://www.nuget.org/packages/InfluxDB.Client/). Add the nuget to the project and copy the example code and you are off.   Result; So after a couple of hours, filling out the methods of our ILogTarget implementation, we end up with an Experior plugin (in this case I named it ‘InfluxDbLogTargetPlugin’) that is able to receive all Experior logs, and relay them to a running InfluxDb server. I added some extra options to convert logs into ‘syslog’ format etc. – just for the fun of it – it was that simple.   Seems to be working great, but I need play around with doing a proper logview dashboard (below is just raw-data viewing using the built-in InfluxDb UI). Sounds like the older 1.8 version had a syslog logviewer built in, but it was removed from the 2.0 version.   Or perhabs Grafana has a better one. Grafana is another interresting visualization tool that can easily be used in conjuction with InfluxDb.   Thoughts have already started on doing a plugin that provides means for logging simulation/emulation data to InfluxDb and using one of the visualization packets on top of it – that could also be cool 👾   Happy logging 😺🏍   ‍  
View full article
Kasper.Vestrup Explorer
‎2026-01-09 01:26 AM

on ‎2026-01-09 01:26 AM

Labels:
  • Exp-7 Developer
  • Experior 7
54 Views

Rigidpart - Static

Static allows a higher complexity level for 3D models, meaning it loads all materials on an object and recreates it as it was created in the 3D design software.   This is particularly relevant for Parts in Experior – such as conveyor belts, machinery, sensors and custom graphical objects – which are usually more complex than a single box-shaped Load variation. It should be noted that some models – such as a Conveyor belt – is actually a collection of different simpler model shapes stitched together rather than one mesh.   Models deriving from Static relates to models that either applies forces to other 3D model objects (conveyors), or models that are static in the scenery. A conveyor applies forces to Loads for instance, whereas a model of a stacked shelf, or a man, can be placed for illustrative purposes or achieving completeness of the Experior 3D model compared to the real world. Most importantly, Static models are not affected by a gravity force.   Static RigidPart models are typically added to Assemblies like conveyors, sensors, gates, sorters for example.   Methods and Properties Static implements physics related properties and methods, as well as overriding some of the basic definitions from RigidPart. Note: We are working on creating a complete list which can be found in the API static Documentation   The following physics related concepts are implemented: CreateActor() NVIDIA Physics core concept, defining an actor that behaves based on physics. A Static Part is added as an actor. A new actor is created each time (in an UpdateActor() method) a property value that affects its functional configuration is changed, such as size or rigid shape. This method is called from a model class which derives from Static. Kinematic related methods A Kinematic = true actor will act as if it has infinite mass, which means it can push regular non-kinematic dynamic actors away, but cannot be pushed back itself. Secondly, if movement is intended for the part, the programmer must define the actor’s movement each time step, which can be useful if it is desirable that the object should follow a specific pre-defined path. Static Parts are instantiated as Kinematic = true, which provides a need for defining methods that handles transformations (TransformActor()). Rigid – matters in defining how the actor behaves when collisions occur. Also defines how precise the collision should be (as in how closely collision detection point matches point on the mesh) – this is also a question of performance, where rigid body shape complexity increases performance cost. Rigid body shape – has the following options: None Box (Default) Rounded Dice Sphere Convex Friction (override) & new methods Enable/Disable() Friction methods can be called to set a Part’s friction coefficient on with its coefficient value or disable entirely. (Physics Engine) For instance, Conveyor belts can have motors attached, where it can be useful to entirely disable friction when a motor is started and instead handle a Load’s movement along the Conveyor in a consistent linear manner. Similarly, when the motor stops, friction is enabled once again to stop the Load’s movement along the Conveyor. Collide() Boolean used to update simulation parameters if the Static Part collided with a Load Part   General related concepts that are implemented: Attach()/UnAttach() Methods related to attaching loads to a Static model, such as a robot picker with a magnet. Takes care of positioning/orientation of the attached loads. Lock/Unlock – Lock/Unlock the Part’s position in Experior. (Bool) Rigid – Get/Set whether the Static Part is a Rigid, which it does not necessarily have to be. If the 3D model imported is for illustration purposes, it does not need to behave with physics related functionality.   Adding a Static Model Part to an Assembly The following code example demonstrates a code excerpt on how a Static model Part is added to an Assembly in Experior, based on the Curve Assembly found in the Conveyor Catalog and corresponding CurveConveyorBelt Part to add.    Note: This excerpt is only a fraction of the full Curve Assembly implementation and should be considered as such, meaning the code snippets will not fully produce the illustrated example.   using Experior.Core.Parts; // Needed for ConveyorCurveBelt reference using Experior.Core.Mathematics; // Needed for Trigonometry reference using Experior.Interfaces; // Needed for Coefficient reference using Experior.Core.Assemblies; // Needed for Assembly reference public class Curve : Assembly { private ConveyorCurveBelt curveBelt; public Curve(CurveInfo info) : base(info) { if(info.friction == null) { info.friction = new Experior.Core.Parts.Friction(); info.friction.Coefficient = Coefficients.Sticky; } curveBelt = new ConveyorCurveBelt(true); curveBelt.Radius = info.radius; curveBelt.Width = info.width; curveBelt.Angle = Trigonometry.Rad2Angle(info.angle); curveBelt.Friction = info.friction; curveBelt.Rigid = true; curveBelt.Color = info.surfacecolor; Add(curveBelt); } }     A simpler example taken from the DeveloperSamples catalog, shows the most basic method of adding a new RigidPart Box to an Assembly, as demonstrated below.    Sample2 Assembly placed in Experior, containing part1 (Blue Box) and part2 (Red Box).   using Experiore.Core.Assemblies; // Needed for Assembly / AssemblyInfo reference using Experior.Core.Parts; // needed for RigidPart/Box reference using System.Windows.Media; // Needed for Colors reference using System.Numerics; // Needed for Vector3 reference public class Sample2 : Assembly { private RigidPart part1, part2; // Constructor public Sample2(AssemblyInfo info) : base(info) { // Add a new RigidPart Box // Color = Blue // Dimensions = (x - length: 0.5m, y - height: 0.5m, z - width: 0.5m) // Local position = (x: 0, y: 2, z: 0) part1 = Add(new Box(Colors.Blue, 0.5f, 0.5f, 0.5f), new Vector3(0, 2, 0)); part2 = Add(new Box(Colors.Red, 0.5f, 0.5f, 0.5f), new Vector3(0, 0, 0)); } }
View full article
Kasper.Vestrup Explorer
‎2026-01-08 05:50 AM

on ‎2026-01-08 05:50 AM

Labels:
  • Exp-7 Developer
  • Experior 7
121 Views

RigidPart - Dynamic

Dynamic is primarily used as the base class for Loads in Experior. Since there is potential for a lot more active Loads than Parts/Machinery in an Experior model, Dynamic implements simplified models, cutting 3D model complexity for performance gains.   A Dynamic load 3D model is collapsed into a streamlined format that strips away some of the functionality seen in Static. For instance, Loads only applies one material color to the entire 3D model instead of iterating through all materials. Visual complexity could be achieved by applying a texture to the model.   Models deriving from Dynamic relates to models (Loads) that act on physics forces applied by other 3D objects (conveyors for instance). Loads are meant to be moved by the NVIDIA PhysX engine, to transport them along conveyor paths in an Experior model. Most importantly, Dynamic models are affected by a gravity force to drive their transportation through an Experior model. In Experior’s Discrete Events mode, Dynamic can be attached to a Load, which will not be affected by physics forces.   Methods and Properties Dynamic implements physics related properties and methods, as well as overriding some of the basic definitions from RigidPart. Note: We are working on creating a complete list which can be found in the API documentation.   The following physics related concepts are implemented: CreateActor() NVIDIA Physics core concept, defining an actor that behaves based on physics. A Dynamic Part is added as an actor. Also implements ReCreateActor(), which calls this method each time a property value affecting its size or rigid shape is modified, setting the newly created actor’s global position/orientation to the previous actor’s values. Kinematic (true/false) A Kinematic = true actor will act as if it has infinite mass, which means it can push regular non-kinematic dynamic actors away, but cannot be pushed back itself. Secondly, if movement is intended for the Part, the programmer must define the actor’s movement each time step, which can be useful if it is desirable that the object should follow a specific pre-defined path. Rigid – Matters in defining how the actor behaves when collisions occur. Also defines how precise the collision should be (as in how closely collision detection point matches point on the mesh) – this is also a question of performance, where rigid body shape complexity increases performance cost. Rigid body shape – has the following options: None Box (Default) Rounded Dice Sphere Convex Linear/Angular Dampening Linear/Angular Velocity Center of Mass Position When the physics engine applies a force to a Load to make it move, the force is applied into its center of mass. By default, a Load’s density is equally distributed over the whole volume of the Load and hence the center of mass of the Load is also its geometrical center. By providing the Center Of Mass Offset Local Position, it is possible to move this center of mass and potentially place 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 Center Of Mass Offset Local Position property provided in the property window of a feeder is a normalised value, where 0:0:0 is center of the Load and 0:1:0 would be at the top-center position. Collision detection (true/false) Default: true Density – used in calculating Load’s weight, which in Experior is Density * Volume. Add Force()/Torque() Sleep()/Wake() – Physics concept of enable/disable. Setting a Load as “Sleeping”, means it will no longer responds to physical forces applied to it, until it is enabled/woken up again.   Adding a Dynamic based Load Custom Load classes in Experior derive from the Load base class in the Experior.Core.Loads namespace, where the custom Load class implements a Part that derives from Dynamic. Let’s look at an example that demonstrates how a EuroPallet load type could be implemented in Experior.   The EuroPallet class defines a EuroPallet constructor which takes a PalletInfo object as an argument, which further derives from LoadInfo class, where info.<insertfield> fields are defined. Inside the constructor, a new Part is created and positioned/oriented correctly alongside updating the info object with the correct information, which ensures the model can be re-created when loaded from a save file.   public class EuroPallet : Load { public EuroPallet(PalletInfo info) : base(info) { Part = new PalletPart(info.randomcolor ? Colors.GetRandomColor() : Info.color, // Part color 1.2f, 0.144f, 0.8f, // Part size (Length, Height, Width) info.density, // Part density EmbeddedResources.EmbeddedResourceLoader.Get("EUROpallet.dae"), // Get embedded 3D model resource info.rigid, // Define Rigid shape this); // ILoad parent Part.Position = Info.position; Part.Orientation = Info.rotation; info.height = ((PalletPart)Part).Height; info.length = ((PalletPart)Part).Length; info.width = ((PalletPart)Part).Width; info.color = Part.Color; } }   The PalletPart class, which derives from Dynamic, gets the correct mesh from an embedded resource by importing it, scales the mesh to input size and sets a centerofmass point value. The latter value matters for physics forces, which are applied to an objects center of mass point. internal class PalletPart : Dynamic { private EmbeddedResource resource; private int textureId = -1; [Browsable(false)] public override int TextureId =>; textureId; public PalletPart(Color color, // Part color float length, // Part length float height, // Part height float width, // Part width float density, // Part density EmbeddedResource resource, // Embedded resource file reference Rigids rigid, // Rigid shape ILoad parent) // ILoad parent : base(parent) { try { this.density = density; this.resource = resource; // Import Embedded resource mesh, its meshdata color and ID reference to mesh texture Importer.GetMesh(resource, out meshData, out this.color, out textureId); // At the time of writing, Experior handles Load coloring with 2 special cases by: // * transparent = random color // * black = mesh color // This if clause means if (input) color != black, set mesh color (this.color) to input color // if (input) color is black, it uses outed mesh color (this.color) as load color // Color handling is to be refactored in a future Experior major version. if (color != System.Windows.Media.Colors.Black) { this.color = color; } this.rigid = rigid; scale = new Vector3(1, 1, 1); Vector3 size = MeshData.BoundingBox.Size; // Calculate proper scalar based on mesh bounding box size if (length > 0 && height > 0 && width > 0) { scale = new Vector3(length / size.X, height / size.Y, width / size.Z); } // Define center of mass point centerofmass = new Vector3(0, -Height / 2.5f, 0); Observers.MeshObjectObserver.Added(this); } catch (Exception se) { Log.Write(se, 0933886); } } }   A CreateEuroPallet() method could then finally be defined as: public static Load CreateEuroPallet(string barcode, float density, Color color, Rigids rigid) { var info = new PalletInfo { barcode = barcode, rigid = rigid, density = density, color = color }; var load = new EuroPallet(info); // Position the load at half the load's height. (Positions the load from its centerpoint). load.Position = new Vector3(0, load.Height / 2, 0); // Add to collection of loads added to the scene. items.Add(load); return load; }   In Experior, the CreateEuroPallet() method is called when the “Feeder” assembly in the Conveyor catalog “feeds” a new load, either from a double-click event on the 3D cube model or pressing the spacebar when it is selected.   Feeder Assembly as it is placed in Experior, not selected.   Feeder and the EuroPallet load type created (random colour applied). 
View full article
Kasper.Vestrup Explorer
‎2026-01-08 05:46 AM

on ‎2026-01-08 05:46 AM

Labels:
  • Exp-7 Developer
  • Experior 7
129 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-05 06:01 AM

on ‎2026-01-05 06:01 AM

Labels:
  • Exp-7 Developer
  • Experior 7
118 Views

Timer.Translate – Performance optimization

The Experior Translate has challenges when coming to performance issues, but it is difficult to fix the challenges without affecting existing solutions using it.   Here is what we decided to do:   The existing property ‘Animate’ has been renamed to ‘AutoUpdatePositions’ (Animate still exist but marked obsolete). Reason for the name change is that not only animation is affected but also positions of Assemblies/Parts added to the translate timer, will not be updated until translation is done.   Code example: // Create a translate timer as per usual: Core.Timer.Translate _translateTimer = new Core.Timer.Translate(); // Configure _translateTimer private void ConfigureTranslateTimer() { _translateTimer.AutoUpdatePositions = false; }   A new method ‘UpdatePositions’ has been added. This allows users to manually update positions of Assemblies/Parts added to the translate timer when AutoUpdatePosition is false.   This solves the problem we used to have with slow simulations when the translate timer is used and with a few extra steps (for the user), there are almost no loss of precision or functionality. If ‘AutoUpdatePositions’ is set to false, simulations using translate timers will run a lot faster. This has 3 side effects:   1.The translation is no longer animated. However, if users implement a real time timer that calls UpdatePositions every 1/30 sec. then animation is back to normal, and the simulation still runs a lot faster.   Code example: // Setup a real time timer somewhere (e.g. in a Controller): System.Timers.Timer updateTimer = new System.Timers.Timer(1/30.0); updateTimer.AutoReset = true; updateTimer.Elapsed += UpdateTimer_Elapsed; // Call UpdatePosition on Elapesed private void UpdateTimer_Elapsed(object sender, ElapsedEventArgs e) { _translateTimer.UpdatePositions(); }   2. Positions are not updated until translation is done. However, if users call UpdatePositions just before asking for a position of any Assembly/Part added to the timer, the return value should be as precise as if AutoUpdatePositions were true.   Code example: // Lets say we need a position of an assembly while it is being translated by _translateTimer _translateTimer.UpdatePositions(); var position = MyAssembly.Position;   3. OnPositionChanged events are not raised on every timestep when AutoUpdatePositions is false, only when UpdatePositions is called by the user. This may have an impact in some project.   How it used to work in Experior 6 and why there is a difference in Experior 7:   In Experior 7 there has been focus on making simulations deterministic. That means a simulation should yield the same results when it is run multiple times and in different environments e.g. on another computer. To accomplish this we needed to separate the UI thread from the engine thread where simulation related calculations are done.   In Experior 6, the UI update rate (which was user adjustable) was directly responsible for initiating the update of assemblies. That means, if the framerate was set to 5, then positions of Assemblies/Parts added to a translate timer would be updated 5 times per real-time second, no matter the simulation time scale. This could in some cases yield different results whether the framerate was set to 5 or 60 and whether timescale was 1 or infinity. That also means if the framerate was set to 0, much fewer calculations were needed and hence the simulations were running very fast, although non deterministic.   In Experior 7, the engine thread is responsible for initiating update of assemblies. When the simulation target time scale is at infinity, the time steps are as large as it takes the computer to do all necessary calculations. If the time scale is 1 (real time), the engine step method inserts pauses in every step to accomplish the target time scale of 1 real-time second. That means the same amount of calculations is needed no matter time scale or framerate and hence the simulations are running slower.
View full article
Kasper.Vestrup Explorer
‎2026-01-05 05:49 AM

on ‎2026-01-05 05:49 AM

Labels:
  • Exp-7 Developer
  • Experior 7
94 Views

Skip signing catalogs/plug-ins

To support various Continous Integration (CI) setups, from Experior version 7.0.23105 onwards, you can now load unsigned catalogs and plug-ins – if using a Developer license.   The feature is two-folded. Part one is the skipping of signing the catalogs and plug-ins – this can be done in one of two ways.   Remove the Experior.Build UsingTask in the csproj – either by removing it entirely or adding a Conditional attribute. Or by configuring the Experior.Build by setting the new attribute ‘Skip=”true”‘.Example: <Experior.Build AssemblyFileLocation=”$(OutputPath)$(TargetFileName)” Debug=”true” Skip=”true”></Experior.Build> Now you are compiling/building the catalog or plug-in without signing it. Previously you would not be able to load the catalog or plug-in in Experior, but with the new version you are able to load them if you are using a valid Developer license.   A usescase could be to save time in CI pipelines. Visual Studio solutions with many plug-ins could use a substantial time just doing the signing process. These steps can now be avoided.   Note:   If you are using a non-developer license, catalog and plug-in checking is done as usual (catalogs and plug-ins must be signed) – meaning checksum and Key checking etc. will be performed as expected.   If you are using a Developer license and a valid ‘Tail’ / signing is found, then it also will be checked as usual. So the new feature is that Experior will allow catalogs and plug-ins without a tail.
View full article
Kasper.Vestrup Explorer
‎2026-01-05 05:47 AM

on ‎2026-01-05 05:47 AM

Labels:
  • Exp-7 Developer
  • Experior 7
209 Views

Resource files

Icons and Mesh folders   Icons and Mesh folders are used to allocate resources such as images and CAD files.   Supported formats are: Image: .png, .jpg, .bmp, .gif, .svg Mesh: .x, .dae, .fbx, .obj, .3ds, .ase, .blend, .stl, .lwo, .dxf    NOTE: Some formats are not fully supported as embedded resources as they reference other files for data. Such as .obj files that reference a .mtl file for their color data. If you have problems loading your resources, try referencing it using the filepath instead of the EmbeddedResourceLoader.   Our Import functionality uses the Assimp open source library, some format features may not be supported. If you run into issues importing your files, try simplifying your imported object. For example, removing an armature or other unnecessary components. See “Import issues” below for notes about unsupported features or issues you may run into when trying to import certain files.   Once a resource has been added to the appropriate folder (Icon/Mesh), set the property Build Action to Embedded Resource.   Accessing resources in the code   Resources are accessed through the public static fields contained in the Internal class Common located in Create.cs internal class Common { public static Experior.Core.Resources.EmbeddedImageLoader EmbeddedImageLoader; public static Experior.Core.Resources.EmbeddedResourceLoader EmbeddedResourceLoader; }   Getting access to images: public override ImageSource Image => Common.EmbeddedImageLoader.Get("Example.png");   Getting access to CAD/Mesh files: var exampleMesh = new Experior.Core.Parts.Model(Common.EmbeddedResourceLoader.Get("Example.stl"));   Import issues We do not currently support COLLADA (.dae) files containing armatures. .obj files as embedded resources do not display any color/shading, since they currently have no way of referencing their .mtl file.
View full article
Kasper.Vestrup Explorer
‎2026-01-05 03:00 AM

on ‎2026-01-05 03:00 AM

Labels:
  • Exp-7 Developer
  • Experior 7
151 Views

Restrict the use of catalogs

When developing custom catalogs you can add catalog restrictions to e.g. only allow specific Experior license IDs to load the catalog. The use case could be that you will restrict catalog usage to internal use only or similar.   There are 2 ways you can restrict catalog usage: using a Build.Config file or using a “Keys” attribute in the csproj   Restriction is opt-in, meaning that if you don’t wish to restrict catalog usage, then the default behaviour is that the catalog is complied without license ID / key restriction and everybody with a valid Experior license and physical access to the catalog will be able to load it.   Wildcards are supported for both subsequent solutions, so adding a license ID like ’02*’ will, allow all licenses starting with ’02’.   Using a Build.Config file: A ‘Build.config’ file can be used in the build process if you want to always restrict catalog usage and apply the restriction for all catalogs being built.   Process:   You create a file named ‘Build.config’. The contents should be valid XML <!--?xml version="1.0" encoding="utf-8"?--> <Key xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> <Items> <string>0102</string> <string>0103</string> <string>02*</string> </Items> </Key>     The ‘Build.config’ file can be placed in one of three locations depending on your setup; Local to Experior.Build.dll Environment variable ‘EXPERIOR_SIGNTOOL_CONF’ %localappdata%\\Xcelgo\\Experior\\SDK\\Build”   Using a ‘Keys’ attribute   The ‘Keys’ attribute is the more explicit way, since here you are explicitly specifying per project (= catalog) which license IDs (“keys”) are allowed to load the catalog – and you can have it under version control since its part of the source code etc.   Process:   In the csproj for the catalog project, you find the signing Task (normally the <Experior.Build … /> element) and add a ‘Keys=”xxxx|yyyy|zz*”‘ attribute, where xxxx|yyyy|zz* are a ‘|’ separated list of license IDs.   Example: <Target Name="PluginSigning" AfterTargets="AfterBuild"> <Experior.Build AssemblyFileLocation="$(OutputPath)$(TargetFileName)" keys="0102|0103|02*"></Experior.Build> </Target>
View full article
Kasper.Vestrup Explorer
‎2026-01-05 02:58 AM

on ‎2026-01-05 02:58 AM

Labels:
  • Exp-7 Developer
  • Experior 7
153 Views

Coordinate System(s)

Experior's Global Coordinate System   Experior 7 implements a left-handed, y-up coordinate system for its 3D environment as illustrated in the figure below, which is the view presented to the user when Experior is opened.   The x-axis is considered the forward vector in Experior. The y-axis is considered the up-vector in Experior.   For some models implemented in Experior, the different axises are also named as follows: x-axis = “Length” y-axis = “Height” z-axis = “Width”   This coordinate system is never moved. Experior's global coordinate system - left-handed, y-up.   Assemblies are placed in the global coordinate system, whereas individual parts in an Assembly are placed relative to the Assembly’s local coordinate system. An Assembly's global position in Experior (Orange dot - (1000mm, 410mm, 1000mm)). Conveyor sides (Boundaries) are objects added to the Assembly, hence they have a local position relative to the Assembly's global position.     To illustrate the concept in another way, the following images show an Assembly with 2 parts (Red/Blue Box).    In the left image, the Assembly is placed at global coordinate (0, 0, 0). The Parts are placed at local coordinates – Red box: (0, 0, 0) and Blue box: (0, 2, 0) respectively. The Blue box also has local Pitch rotation applied.   In the right side image, the Assembly is placed at global coordinate (4, 0, 3), where the individual Parts retain their local coordinate offsets.   An Assembly with 2 Parts (Red/Blue Boxes) placed at global position (0, 0, 0).   An Assembly with 2 Parts (Red/Blue Boxes) placed at global position (4, 0, 3), retaining their local offset positions.   Each Part in an Assembly also has its own local coordinate system, which is mostly relevant for rotations/orientations of the Part around its local center point, as illustrated above with local Pitch rotation applied to the blue Box Part.
View full article
Kasper.Vestrup Explorer
‎2026-01-05 02:50 AM

on ‎2026-01-05 02:50 AM

Labels:
  • Exp-7 Developer
  • Experior 7
99 Views

C# Templates for Experior 7

With a developer license for Experior 7 it is possible to create custom catalogs, controllers, plugins and more in your Experior model. We have three different templates packaged in a .vsix (Visual Studio Integration Extension) file that you can download and run, as long as you have Experior 7 and Visual Studio installed. This .vsix is attached in this article in a zip file - Simply download and extract to run the installer.   To avoid confusion, we recommend removing the old Catalog, Controller and Plugin templates before installing the new ones. Removing old templates   To remove the old Visual Studio templates:   Close Visual Studio   Navigate to the C# visual studio template folder. The standard path for this is: C:\Users\ your username \Documents\Visual Studio 20XX\Templates\ProjectTemplates\(Visual) C#   Delete the zip files named: “Experior-7.0-Catalog-Template.zip”, “Experior-7.0-Plugin-Template.zip” and “Experior-7.0-Controller-Template.zip”.   If you get an error dialog saying: “This extension is already installed to all applicable products” You can navigate to: c:\users\[username]\AppData\Local\Microsoft\VisualStudio\17.0[hashid]\Extensions\   If any of the folders here contain Experior template files. Delete the folder. Then try running the VSIX installer again.   Output path   By default, the output path of the templates is set to the default installation location of the Experior executable.   This is defined by the environment variable: “EXPERIOR7_BIN” which is created when you install Experior 7 - by default: (C:\Xcelgo\Xcelgo Experior 7).   This means that when you build your project, the project output (*.dll) is created in that folder.   Make sure “Copy local” is set to “false” for Experior specific dll’s.   You can change this output path through the project properties. But in order for Experior to load it, you need to provide an External Libraries location.   This can be done in several ways: – Through the catalog selector’s External Libraries dropdown when Experior is started with “-config” – Through using a Startup Configuration file when Experior is started with “-startupconfiguration <file>” – Through an External Libraries path when Experior is started with “-libs <path>”   You can also manually drag and drop the dll from the folder you build to, into the Experior installation folder.   Warning:  When using an External Library folder, any dll that is present in both the External Library folder and the Experior installation folder causes errors.  
View full article
Kasper.Vestrup Explorer
‎2026-01-05 02:46 AM

on ‎2026-01-05 02:46 AM

Labels:
  • Exp-7 Developer
  • Experior 7
373 Views
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