Skip to main content

PositionAxesMap

Manages the mapping between position variables and motion axes, enabling position-based motion control.

Namespace: ControlBee.Models

Implements: IPositionAxesMap

Overview

PositionAxesMap connects position variables (like Position1D, Position3D) to physical motion axes. This mapping enables:

  • Position Teaching - Read current axis positions into position variables
  • Position Motion - Move multiple axes to stored positions
  • UI Generation - Show which axes are associated with positions
  • Validation - Verify axes are available before motion

Each actor has its own PositionAxesMap instance, accessible via the Actor.PositionAxesMap property.

Internal Storage

private readonly Dictionary<string, IAxis[]> _map;
private readonly Dictionary<IVariable, IAxis[]> _variableMap;

The class maintains two dictionaries:

  • _variableMap - Temporary storage during actor construction
  • _map - Final mapping keyed by variable item path

The mapping is finalized when UpdateMap() is called by the framework.

Methods

Add

public void Add(IVariable variable, IAxis[] axes)

Adds a mapping between a position variable and an array of axes.

Parameters:

  • variable — The position variable (Position1D, Position2D, Position3D, etc.)
  • axes — Array of axes that correspond to this position

Usage Example:

public class StageActor : Actor
{
public Variable<Position1D> LoadPosX = new(VariableScope.Local);
public Variable<Position3D> PickPos = new(VariableScope.Local);

public IAxis X, Y, Z;

public StageActor(ActorConfig config) : base(config)
{
X = config.AxisFactory.Create();
Y = config.AxisFactory.Create();
Z = config.AxisFactory.Create();

// Map position variables to axes
PositionAxesMap.Add(LoadPosX, [X]); // 1D position maps to X axis
PositionAxesMap.Add(PickPos, [X, Y, Z]); // 3D position maps to X, Y, Z axes
}
}

Get

public IAxis[] Get(string itemPath)

Retrieves the axes associated with a position variable by its item path.

Parameters:

  • itemPath — The item path of the position variable

Returns: Array of axes mapped to this position

Throws: PlatformException if the item path is not found in the map

Usage Example:

// Get axes for a position
var axes = PositionAxesMap.Get("PickPos");
foreach (var axis in axes)
{
Console.WriteLine($"Axis position: {axis.ActualPosition}");
}

Note: This method is typically used internally by the framework. User code usually doesn't call it directly.

UpdateMap

public void UpdateMap()

Finalizes the mapping by transferring entries from _variableMap to _map. Called by the framework after actor construction.

Note: Called automatically by the framework. User code should not call this method.

Usage Patterns

1. Single Axis Position

public class LinearStageActor : Actor
{
public Variable<Position1D> LoadPos = new(VariableScope.Local);
public Variable<Position1D> UnloadPos = new(VariableScope.Local);

public IAxis X;

public LinearStageActor(ActorConfig config) : base(config)
{
X = config.AxisFactory.Create();

// Map both positions to the same X axis
PositionAxesMap.Add(LoadPos, [X]);
PositionAxesMap.Add(UnloadPos, [X]);
}

[Function]
public void MoveToLoad()
{
LoadPos.Value.MoveAndWait(); // Moves X axis to LoadPos position
}

[Function]
public void TeachLoadPos()
{
LoadPos.Value.TeachCurrent(); // Reads X axis position into LoadPos
}
}

2. Multi-Axis Position

public class PickerActor : Actor
{
public Variable<Position3D> PickPos = new(VariableScope.Local);
public Variable<Position3D> PlacePos = new(VariableScope.Local);

public IAxis X, Y, Z;

public PickerActor(ActorConfig config) : base(config)
{
X = config.AxisFactory.Create();
Y = config.AxisFactory.Create();
Z = config.AxisFactory.Create();

// Map 3D positions to all three axes
PositionAxesMap.Add(PickPos, [X, Y, Z]);
PositionAxesMap.Add(PlacePos, [X, Y, Z]);
}

[Function]
public void MoveToPick()
{
// Moves X, Y, and Z axes simultaneously to PickPos
PickPos.Value.MoveAndWait();
}

[Function]
public void TeachPickPos()
{
// Reads X, Y, Z positions into PickPos
PickPos.Value.TeachCurrent();
}
}

3. Mixed Dimensions

public class ComplexStageActor : Actor
{
public Variable<Position1D> LoadPosX = new(VariableScope.Local);
public Variable<Position2D> ScanPosXY = new(VariableScope.Local);
public Variable<Position3D> PickPosXYZ = new(VariableScope.Local);

public IAxis X, Y, Z;

public ComplexStageActor(ActorConfig config) : base(config)
{
X = config.AxisFactory.Create();
Y = config.AxisFactory.Create();
Z = config.AxisFactory.Create();

// Different dimensional positions
PositionAxesMap.Add(LoadPosX, [X]); // 1D - X only
PositionAxesMap.Add(ScanPosXY, [X, Y]); // 2D - X and Y
PositionAxesMap.Add(PickPosXYZ, [X, Y, Z]); // 3D - X, Y, and Z
}
}

4. Axis Reuse

public class DualArmActor : Actor
{
// Left arm positions
public Variable<Position3D> LeftPickPos = new(VariableScope.Local);
public Variable<Position3D> LeftPlacePos = new(VariableScope.Local);

// Right arm positions
public Variable<Position3D> RightPickPos = new(VariableScope.Local);
public Variable<Position3D> RightPlacePos = new(VariableScope.Local);

public IAxis LeftX, LeftY, LeftZ;
public IAxis RightX, RightY, RightZ;

public DualArmActor(ActorConfig config) : base(config)
{
// Create axes for both arms
LeftX = config.AxisFactory.Create();
LeftY = config.AxisFactory.Create();
LeftZ = config.AxisFactory.Create();

RightX = config.AxisFactory.Create();
RightY = config.AxisFactory.Create();
RightZ = config.AxisFactory.Create();

// Map left arm positions to left axes
PositionAxesMap.Add(LeftPickPos, [LeftX, LeftY, LeftZ]);
PositionAxesMap.Add(LeftPlacePos, [LeftX, LeftY, LeftZ]);

// Map right arm positions to right axes
PositionAxesMap.Add(RightPickPos, [RightX, RightY, RightZ]);
PositionAxesMap.Add(RightPlacePos, [RightX, RightY, RightZ]);
}
}

Error Handling

Missing Mapping

try
{
var axes = PositionAxesMap.Get("UnmappedPosition");
}
catch (PlatformException ex)
{
Console.WriteLine($"Position not mapped: {ex.Message}");
}

Common causes:

  • Forgot to call PositionAxesMap.Add() in constructor
  • Typo in item path
  • Variable not properly initialized

Solution:

public MyActor(ActorConfig config) : base(config)
{
X = config.AxisFactory.Create();

// Don't forget to add mapping!
PositionAxesMap.Add(MyPosition, [X]);
}

Best Practices

1. Add Mappings in Constructor

// ✅ Good - Mappings added in constructor
public MyActor(ActorConfig config) : base(config)
{
X = config.AxisFactory.Create();
PositionAxesMap.Add(LoadPos, [X]);
}

// ❌ Bad - Mapping added later (won't work)
public MyActor(ActorConfig config) : base(config)
{
X = config.AxisFactory.Create();
}

public override void Start()
{
base.Start();
PositionAxesMap.Add(LoadPos, [X]); // Too late!
}

2. Map All Position Variables

// ✅ Good - All positions mapped
public MyActor(ActorConfig config) : base(config)
{
X = config.AxisFactory.Create();

PositionAxesMap.Add(LoadPos, [X]);
PositionAxesMap.Add(UnloadPos, [X]);
PositionAxesMap.Add(ProcessPos, [X]);
}

// ❌ Bad - Missing mapping
public MyActor(ActorConfig config) : base(config)
{
X = config.AxisFactory.Create();

PositionAxesMap.Add(LoadPos, [X]);
// UnloadPos not mapped - will throw exception when used!
}

3. Correct Axis Order

// ✅ Good - Correct axis order (X, Y, Z)
PositionAxesMap.Add(PickPos, [X, Y, Z]);

// ❌ Bad - Wrong axis order
PositionAxesMap.Add(PickPos, [Z, Y, X]); // Will move to wrong positions!

4. Match Dimensions

// ✅ Good - 3D position with 3 axes
Variable<Position3D> Pos = new(VariableScope.Local);
PositionAxesMap.Add(Pos, [X, Y, Z]);

// ❌ Bad - Dimension mismatch
Variable<Position3D> Pos = new(VariableScope.Local);
PositionAxesMap.Add(Pos, [X, Y]); // Missing Z axis!

Integration with Position Variables

Position variables use PositionAxesMap internally:

// When teaching a position
LoadPos.Value.TeachCurrent();
// Internally:
// 1. Gets axes from PositionAxesMap
// 2. Reads each axis's ActualPosition
// 3. Stores in position variable

// When moving to a position
LoadPos.Value.MoveAndWait();
// Internally:
// 1. Gets axes from PositionAxesMap
// 2. Commands each axis to move
// 3. Waits for all axes to complete

See Also