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
- IPositionAxesMap Interface - Interface definition
- Variable System Guide - Position-axis mapping
- Position Types - Position1D/2D/3D/4D documentation
- IAxis Interface - Motion axis interface