< All Topics

Assembly class

Assemblies are model entities that are chosen from a catalog and are dragged onto the working area.

All assemblies derive from the class Experior.Core.Assemblies.Assembly which itself implements the IEntity interface.

The constructor of an Assembly always contains an object deriving from the AssemblyInfo class as an argument, Assembly(AssemblyInfo info).

This is used to support the mechanism for saving/loading a model. When saving a model all AssemblyInfo objects are serialized into an Assemblies.XML file and zipped into the Experior model file.

When loading the model Experior unzips the Experior model file and deserializes the Assemblies.XML file. For each deserialised AssemblyInfo object the appropriate constructor is called.

When dragging the assembly from a catalog to the working area the methods of the catalog are used to create an appropriate AssemblyInfo object and then pass this object into the constructor of the matching Assembly class.

Note: After an assembly is created by dragging it onto the working area its Inserted method is called. This is not the case when the assembly is created by loading the model.

 

Main methods/properties of the Experior.Core.Assemblies.Assembly class:

Configuration related methods/properties

Add(IEntity entity): This will make the current assembly the Parent entity of the given IEntity. It will also add the given entity to its list of entities (See property Entities)

Remove(IEntity entity): This method will remove the given entity from the list of entities of this assembly and will set the Parent property of the entity back to null. 

bool Configured: This getter property indicates whether the current assembly is configured (this will be the case when RigidParts ar subassemblies have been added to the current assembly)

bool Embedded: This getter/setter property indicates whether this assembly is embedded into another entity or not. When the Embedded property is true the assembly will not be serialized separately when saving the model, instead it will be serialized inside the xml tags of the parent assembly. 

List<Experior.Core.IEntity> Entities: This getter property returns the list of entities that were added to the current assembly.

IEntity Parent: This getter property returns the parent entity of the current assembly. If the assembly is not added to another entity then the Parent property remains null.

 

User interface related methods/properties

MouseDown(): This method is called when the current assembly is selected and the user presses the mouse button.

MouseUp(): This method is called when the current assembly is selected and the user releases the mouse button.

KeyDown(System.Windows.Forms.KeyEventArgs e): This method is called when the current assembly is selected and the user presses a keyboard key. The pressed key can be derived from the given KeyEventArgs e.

KeyUp(System.Windows.Forms.KeyEventArgs e): This method is called when the current assembly is selected and the user releases a pressed a keyboard key. The released key can be derived from the given KeyEventArgs e.

Example:

public override void KeyDown(System.Windows.Forms.KeyEventArgs e)
{
    // change viewpoint when 5 is pressed in the numpad
    if (e.KeyCode == System.Windows.Forms.Keys.NumPad5)
    {
        Experior.Core.Environment.Scene.Camera.JumpTo(this.ViewPoint);
        Vector3 target = this.CalculateTarget();
        Experior.Core.Environment.Scene.Camera.Target = target;
        float calculatedRadius = Trigonometry.Length(this.ViewPoint, target);
        Experior.Core.Environment.Scene.Camera.Radius = calculatedRadius - 0.15f;
    }
}

bool Selectable: This getter/setter property allows to control whether the current assembly can be selected (e.g. by clicking on it).

bool Selected: This getter property returns true if the current assembly is selected.

Motor related methods/properties

InsertMotor(Electric motor): This method is called when the user inserts a motor to the current assembly using the context menu (right clicking on the selected assembly)

InsertMotor(Electric motor, string category): This method is called when the user inserts a motor to the current assembly by selecting the category in the context menu.
E.g. below shown context menu will result in a call of InsertMotor with a newly created vector motor and category UP/DOWN.

RemoveMotor(Electric motor): This method is called to remove the previously inserted motor from the assembly

RemoveMotor(Experior.Core.Parts.Arrow arrow): This method is called to remove the previously inserted motor from the assembly by clicking on the associated motor arrow.
Below you see some examples of usage of the Motor related methods:

Typically the usage of motors in assemblies involves:

  • In the constructor of the assembly specify what types of motors can be added through the context menu. E.g:
            Menu.Motors.Types.Clear();
            Menu.Motors.Add(typeof(Surface));
            Menu.Motors.Add(typeof(Vector), "UP/DOWN");
            Menu.Motors.Add(typeof(Vector), "LEFT/RIGHT");
  • In the constructor of the assembly insert the motors that were previously saved in the Info object:
        InsertMotor(Experior.Core.Motors.Motor.Get(info.motorsurfacename));
        InsertMotor(Experior.Core.Motors.Motor.Get(info.updownmotorvectorname),"UP/DOWN");
        InsertMotor(Experior.Core.Motors.Motor.Get(info.leftrightmotorvectorname),"LEFT/RIGHT");
  • Override the InsertMotor methods to internally keep track of the motors that are inserted (e.g. put them in the proper local fields, maybe create a motor arrow, take into account name changes of the motors,…). Below you find an example:
public override void InsertMotor(Electric motor)
{
    if (motor == null)
    return;
    if (motor is Surface)
    {
        base.InsertMotor(motor);
        surfacemotor = motor;
        motor.NameChanged += new Motor.NameChangedEvent(SurfaceMotorNameChanged);
        if (belt != null)belt.SurfaceMotor = motor;
    }
}

public override void InsertMotor(Electric motor, string category)
{
    if (motor == null)
    return;
    if (motor is Surface)
    {
        InsertMotor(motor);
    }
    else if (motor is Vector)
    {
        if (category == "UP/DOWN")
        {
            if (updownmotorvector!= null)
            RemoveUpDownVectorMotor();

            Info.updownmotorvectorname= motor.info.name;
            updownmotorvector= (Vector)motor;
            updownmotorvector.NameChanged += new Electric.NameChangedEvent(motorvector_MotorNameChanged);
            CreateMotorArrow(updownmotorvector);
            Add(updownmotorvector);
        }
        else if (category == "LEFT/RIGHT")
        {
            if (leftrightmotorvector!= null)
            RemoveLeftRightVectorMotor();

            Info.leftrightmotorvectorname= motor.info.name;
            leftrightmotorvector= (Vector)motor;
            leftrightmotorvector.NameChanged += new Electric.NameChangedEvent(leftrightmotorvector_MotorNameChanged);
            CreateMotorArrow(leftrightmotorvector);
            Add(leftrightmotorvector);
        }
    }
    else base.InsertMotor(motor, category);
}
  • In case you want to allow the user to change the inserted motor through the property window than you have to add the needed property and annotate them with the proper attributes. When you use a string property to set/get a motor you need to specify the proper System.ComponentModel.TypeConverterAttribute (for a Vector motor this is Experior.Core.Motors.Vector.Converter, for a surface motor this is Experior.Core.Motors.Surface.Converter). To change the motor in the setter of the property you first verify whether a motor exists for the given name and then you call the appropriate InsertMotor method as you can see in below example:
/// <summary>
/// Gets or sets the vector motor used for UP/DOWN movement.
/// </summary>
/// <value>The vector motor.</value>
[TypeConverter(typeof(Vector.Converter))]
[PropertyAttributesProvider("DynamicPropertyVectorMotor")]
[DisplayName("UpDownVectorMotor"),CategoryAttribute("Motor"),DescriptionAttribute("Vector motor for UP/DOWN movement")]
public virtual string UpDownMotor
{
    get
    {
        if (((MyAssemblyInfo)Info).updownmotorvectorname== null)
        return string.Empty;
        return ((MyAssemblyInfo)Info).updownmotorvectorname.ToString();
    }
    set
    {
        if (Experior.Core.Motors.Motor.Items.ContainsKey(value))
        InsertMotor(Experior.Core.Motors.Motor.Items[value], "UP/DOWN");
    }
}

Miscellaneous methods/properties

LocalRotation(Vector3 localRotationPoint, float DeltaYaw, float DeltaPitch, float S): Will rotate the current assembly around the given localRotationPoint with the given angles. This will only work if the assembly had been added to a parent assembly. This method will only change the LocalPosition of the assembly with respect to the parent assembly, while keeping the LocalYaw, LocalRoll and LocalPitch constant.

InsertActionPoint(ActionPoint ap): This method is called when the user inserts an action point to the current assembly by clicking on the “Insert ActionPoint”  of its context menu:

Above choice for inserting action points ion the context menu was created by:

    Menu.ActionPoints.Add(typeof(Core.Routes.ActionPoint));
    Menu.ActionPoints.Add(typeof(Core.Routes.Sensor));

bool InvokeRequired: Some methods in Experior are bound to a specific thread (e.g. main engine thread) and are not thread safe. Therefore, if you are calling an method from a different thread, you must use one of the Experior’s invoke methods (Experior.Core.Environment.Invoke) to marshal the call to the proper thread. This InvokeRequired property can be used to determine if you must call an invoke method, which can be useful if you do not know about the different threads. See also here.

InvokeRefresh(): This will schedule the engine to call the Refresh method of the current assembly

Refresh(): This method is called to update the internals of the assembly when some of its properties have changed. It can be used to delete/create subparts
 

Inserted(): This method is called by Experior after the user has dragged the current assembly from the catalog onto the workarea. It is not called when the assembly is placed on the workarea by loading an Experior model.

Render(): This method is called by Experior each time the current assembly is rendered (amount of times is determined by the FPS setting). The base Render methods makes sure that it also calls the Render method of all parts and assemblies that were added to the current assembly.

Reset(): This method is called when the user resets the model (e.g. using Ctrl-R). You can e.g. override this method to reset a linked motor or a custom counter:

public override void Reset()
{
    if (motorvector != null)
    motorvector.Reset();
    loadcount=0;
    base.Reset();
}

Step(float deltatime): This method is called in PhysX mode each time the physics engine advances the time. The delta time is passed as an argument in the method. In discrete mode the Step method of an assembly is not automatically called when time advances but if needed the assembly can subscribe to it:

Experior.Core.Environment.Scene.Step += new Experior.Core.Environment.Scene.StepEvent(Step);

The Step method is typically used to set states, move parts and or subassemblies.

Example where a scanning sensor is moved up and down and sends a signal if gets beyond a given height:

public override void Step(float deltatime)
{
    base.Step(deltatime);
    if (movescansensor)
    {
        if (vectormotor != null && vectormotor.Running)
        {
            // change the relative position of the scan sensor according to the speed en specified direction of the vector motor
            scansensor.LocalPosition += vectormotor.CurrentSpeed * deltatime * vectormotor.VectorDirection;
            if (scansensor.LocalPosition.Y > SlowZoneHeight)
            {
                ((TestAssemblyInfo)Info).plcSlowZone.On();
                vectormotor.AlternativeSpeed();
            }
            if (scansensor.LocalPosition.Y > MaxLimitHeight)
            {
                vectormotor.Backward();
            }
            else if (scansensor.LocalPosition.Y < MinLimitHeight)
            {
                vectormotor.Forward();
                vectormotor.Stop();
            }
        }
    }
}

Grouping related methods/properties

UnGroup(): This will Ungroup the current assembly with all other assemblies it is grouped with.
UnGroup(Experior.Core.Assemblies.Assembly assembly): This will ungroup the given assembly from the current assembly. The call is ignored if the given assembly was not grouped to the current one.
AssemblyDictionary<string, Assemblies.Assembly> Grouped: This returns a dictionary containing all the assemblies the current assembly is grouped with. The Key being used in the dictionary is the name of the grouped assembly, while the Value is the grouped assembly itself. You can use this dictionary to iterate over all assemblies that are grouped with the current one.

foreach (KeyValuePair<string, Assembly> kvp in this.Grouped)
{
    Experior.Core.Environment.Log.Write("Assembly " + this.Name + " is grouped with assembly " + kvp.Key );
}

string Category: This getter property returns the category to which the current assembly belongs and which is used to classify the assembly in the tree of the Solution Explorer.

Color Color: This getter/setter property controls the current color of the assembly.

SolutionExplorer related methods/properties

bool Deletable: This getter property controls whether the current assembly can be deleted 

void Dispose(): This method is called when the current assembly is deleted. It is usually overriden to unsubscibe from events that the assembly had subscribed to. 

bool Enabled: This getter/setter property controls whether the current assembly is enabled (value equals true) or disabled (false). In case the assembly is disabled it is not taken into account by the discrete event engine

bool ListSolutionExplorer: This getter/setter property controls whether the current assembly should be listed in the Solution Explorer.

bool Locked: This getter/setter property allows to lock/unlock the current assembly. When the assembly is locked it will change color to Colors.LOCKEDCOLOR (Yellow by default).

bool Movable: This getter/setter property controls whether the assembly can be moved or not.

bool Warning: This getter property returns true if the assembly should be shown with a warning icon superposed on the normal icon in the Solution Explorer. If you want to specify yourself when this should be the case then override the property. See example below:

public override bool Warning
{
    get
    {
        if (((TestAssemblyInfo)Info).plcSlowZone.Warning)return true;
        return false;
    }
}

Positioning related methods/properties

Matrix Orientation: This property returns or sets the global orientation of the current assembly as defined in the Microsoft.DirectX.Matrix structure.
Vector3 Position: This property returns or sets the global 3 dimensional coordinates of the center of the assembly
Vector3 LocalPosition: This property returns or sets the relative 3 dimensional coordinates of the center of the assembly with respect to its parent object
float LocalYaw: This getter/setter property reflects the rotation angle (in radians) of the current assembly around the Y-axis of its parent object.
float LocalPitch: This getter/setter property reflects the rotation angle (in radians) of the current assembly around the X-axis of its parent object.
float LocalRoll: This getter/setter property reflects the rotation angle (in radians) of the current assembly around the Z-axis of its parent object.
Matrix LocalOrientation: This property returns or sets the relative orientation of the current assemblywith respect to its parent object as defined in the Microsoft.DirectX.Matrix structure
float Yaw: This getter/setter property reflects the rotation angle (in radians) of the current assembly around the global Y-axis.
float Pitch: This getter/setter property reflects the rotation angle (in radians) of the current assemblyaround the global X-axis.
float Roll: This getter/setter property reflects the rotation angle (in radians) of the current assembly around the global Z-axis

Examples of these can be found in Assembly Configuration.

Was this article helpful?
How can we improve this article?
Please submit the reason for your vote so that we can improve the article.
Previous Assembly
Next Assembly Configuration