Motion control classes
The system uses five linear motion devices:
  • x and y stages for tile scanning and cutting.
  • a linear actuator for vertical motion of the x and y stages before cutting.
  • a PIFOC for rapid imaging of multiple optical sections in one physical section.
  • an optional coarse objective z-stage for positioning the imaging plane at the cutting plane. This isn't controlled by BakingTray.
The design principle of BakingTray is that each hardware item is associated with an abstract class. Hardware are grouped in reasonable ways using classes. e.g.
  • Each physical device that provides linear motion is represented by an abstract linearstage class.
  • Each physical control device for each actuator or stage is represented by an abstract linearcontroller. One more linearstages can be attached to each linearcontroller.
  • The BT class brings together the above and also controls ScanImage.
You must set up your concrete classes so that the following conventions are maintained: a) The linear actuator that handles the stage jack (which pushes the sample up and down) is at zero when fully lowered. Upwards locations correspond to posititive numbers. b) The X and Y stages are zero when at the mid-point of their travel ranges. c) -x is left and +x is right. d) -y is towards you and +y is away from you.
An abstract linearstage class declares the methods and properties used to control an abstract linear motion device. The linearstage class can not be instantiated. Methods are defined in concrete classes (which can be instantiated) that inherit linearstage. Whilst it is not necessary for MATLAB classes to be designed this way, the linearstage class serves as a useful starting point for users wishing to write new concrete classes to control custom hardware. To aid this, linearstagecontains extensive comments describing the assumed behavior of each abstract method it declares.
The linearstage is mainly in charge of defining the physical properties of the motion. e.g.
  • The ID of the stage
  • Stores the current position
  • The position units
  • The acceleration
  • Target speed
  • Range of motion (hard and soft limits)
The linearcontroller creates a consistent interface between the controller API (e.g. the manufacturer-specific motion commands) and Baking Tray. Thus the linearcontroller has methods that do the following sorts of things:
  • absoluteMove
  • stopAxis
  • setMaxVelocity
  • etc, etc
Of course the linearcontroller must perform these actions on some physical device. It performs these actions on one or more linearstage stage objects with which it is associated. The linearcontroller contains an attachedStage property. To this we attach one stage object. Say a single physical controller handles both the X an Y stages. We would attach it twice: BT.xAxis and BT.yAxis. Each will have a different stage. The author of the linearcontroller for this stage type is responsible for having the controller read which stage it's attached to and send the correct command out.

How motion control classes are "assembled" when BakingTray starts

When you run BakingTray MATLAB creates an instance of the object BT. This is what the line hBT = BT(BTargs{:}); does in the the BakingTray.m file. In the constructor of BT you will see obj.componentSettings=BakingTray.settings.readComponentSettings; where we extract the settings for the hardware. This are read from the componentSettings.m file in the SETTINGS directory (For more information on this file see here. A little further down in the constructor you will see that the method attachMotionAxes is used to build control classes based on the provided settings. This is done via the buidlMotionComponent function in code\components\motion.

Annotated example: connecting to a PI C-891 at the command line

This example shows how to connect to a PI C-891 motion controller and associated stage at the command line without reference to other aspects of BakingTray described above. This is essentially what is done in the build_C891_stages sub-function in buildMotionComponent.
>> STAGE = genericPIstage;
>> STAGE.axisName='someName'; %Does not matter for this toy example
>> PIC891 = C891(STAGE); %Create control class
>> controllerID.interface='usb'; %We will connect via USB...
>> controllerID.ID= '116010269'; %Using the serial number of the C891
Now we are ready to communicate with the device and connect to it:
>> PIC891.connect(controllerID)
Loading PI_MATLAB_Driver_GCS2 ...
PI_MATLAB_Driver_GCS2 loaded successfully.
Attempting to connect to C-891 with serial number 116010269
If you saw no errors, you can now do stuff like move the stage:
>> PIC891.absoluteMove(0)
ans =