Skip to content

GetMovers()

InfoStations (internal to XPU component) are responsible for delivering to the Application Station a buffer of interface pointers which the Application Station then uses to command motion. The template function block FB_XTS_StationBase includes a method GetMovers(), which handles basic mover acquisition and positioning.

An explanation of this base logic may be useful to those seeking to develop custom station types.

The Code

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
CASE SequenceState OF
    0:
        IF (NumberOfAssignedMovers < NumberOfStops) THEN
            SequenceState := SequenceState + 10;
        ELSE
            SequenceState := 40;
        END_IF

    10:
        IF ipInfoStation.GetMover() THEN
            // Ask for a new mover          
            SequenceState := SequenceState + 10;
        END_IF

    20:
        //Make sure we don't page fault
        IF MoverQueue.LastMover <> 0 THEN
            // Call new mover to this station--station positions go front-to-back
            StopPosition := StopPositions[NumberOfStops - (NumberOfAssignedMovers - 1)];
            StopPosition := GetStopPosition(StopPosition);
            IF MoverQueue.LastMover.MoveAbsoluteCA(StopPosition, TRUE, FALSE) THEN
                SequenceState := SequenceState + 10;
            END_IF
        END_IF

    30:
        // Make sure we have the correct number of movers
        IF NumberOfAssignedMovers = NumberOfStops THEN
            SequenceState := SequenceState + 10;
        ELSE
            SequenceState := 10;
        END_IF

    40:
        //Wait for all movers to arrive at their assigned positions
        MoverTracker.Clear();
        ipMovers := MoverQueue.Queue;
        FOR i := 1 TO NumberOfStops DO
            IF ipMovers[i] <> 0 THEN
                IF NOT ipMovers[i].Busy THEN
                    StopPosition := StopPositions[NumberOfStops - (i - 1)];
                    StopPosition := GetStopPosition(StopPosition);
                    IF ipMovers[i].IsMoverInPosition(StopPosition) THEN
                        MoverTracker.Set(i);
                    END_IF
                END_IF
            END_IF
        END_FOR

        IF MoverTracker.NumberCompleted = NumberOfStops THEN
            SequenceState := SequenceState + 10;
        END_IF

    50:
        SequenceState := 0;
        GetMovers     := TRUE;
END_CASE

The Intent

A basic CASE state machine is executed, with an inner loop (states 0-30) repeating until the correct number of movers (based on Stop Positions configured for the InfoStation) have been acquired. The logic waits until all movers have arrived at their assigned positions before returning TRUE, indicating to the caller that all movers have arrived.

  • State 0 - Check the buffer depth to see if we need another mover
  • NumberOfAssignedMovers is a property that returns the number of movers in the buffer MoverQueue. MoverQueue is actually a pointer to the buffer function block that lives inside the FB_XTS_InfoStation that is assigned to this I_XTS_ApplicationStation (via the InfoStation property). This pointer is managed automatically.
  • NumberOfStops is a property that returns the number of stop positions that have been defined for this InfoStation
  • State 10 - Ask our InfoStation to get another mover
  • The GetMover() method will return TRUE when a new mover has been added to the buffer
  • This logic is handled internally in the XPU component
  • Movers will only be passed from the upstream I_XTS_ApplicationStation if that station has set its CanReleaseMover property to TRUE
  • State 20 - Get the next stop position and send our new mover there
    • StopPositions is an array of positions that corresponds to the Stop Positions set for this InfoStation
    • Stop Positions as set using the XTS configurator are relative to the Start Position of the station!
    • They must be transformed according to the Track this I_XTS_ApplicationStation is assigned to
    • Most configurations only include one track
    • GetStopPosition() will calculate the position on the track that we will then command our new mover to
  • State 30 - Check to see if we have the required number of movers
  • State 40 - Wait for all movers to arrive at their assigned position
    • MoverTracker is a simple way of tracking which movers have successfully completed a task so that we don't issue the same command many times
    • ipMovers gets a copy of the MoverQueue.Queue. This is required so that we can index against the array of I_XTS_Mover
    • If I_XTS_Mover.Busy is set, a command is still in process
    • We get the track position for each Stop Position and check that the mover's actual position is within an acceptable range
    • This range is defined as Stop Position +/- NC Parameter Target Position Window

image - State 50 - Dead Scan to return true and clean up the state machine

Queue Logic

FB_XTS_QueueStation overrides the above state machine and removes the 'in position' checks.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
CASE SequenceState OF
    0:
        //Don't combine this with state 20 -- there is a dead scan for method cleanup/returns
        IF CanAcceptMover THEN
            SequenceState := SequenceState + 10;
        END_IF

    10:
        IF ipInfoStation.GetMover() THEN
            // Ask for a new mover      
            SequenceState := SequenceState + 10;
        END_IF

    20:
        //Make sure we don't page fault
        IF MoverQueue.LastMover <> 0 THEN
            // Call new mover to this station--use only stop position 1
            StopPosition := StopPositions[1];
            StopPosition := GetStopPosition(StopPosition);
            IF MoverQueue.LastMover.MoveAbsoluteCA(StopPosition, TRUE, FALSE) THEN
                SequenceState := 0;
            END_IF
        ELSE
            SequenceState := 0;
        END_IF
END_CASE