Skip to main content

Scheduler

Overview

PortDIC provides a substrate transfer scheduler (ISchedulerHandler) for semiconductor equipment that automates robot arm movement between locations (Load Ports, Process Chambers, Transfer Modules). It implements a pipeline dual-arm scheduling algorithm with BFS shortest-path routing and SEMI E90-aligned substrate state tracking.

Key characteristics:

  • Pipeline scheduling — overlaps pick/place operations for higher throughput
  • BFS shortest-path routing between named locations
  • Dual-arm exchange (simultaneous get + put at the same station)
  • SEMI E90 substrate state model (AtSourceInTransferAtDestination → …)
  • 30-second per-step transfer timeout with cancellation support
  • Singleton — one ISchedulerHandler instance shared across all [Controller] classes

Quick Setup

1. Define locations and arms

using Portdic;

[Controller]
public class TransferController
{
[TransferHandler]
public ISchedulerHandler Scheduler { get; set; }

[Preset]
public void Preset()
{
Scheduler.SetLogger(@"C:\Logs\Equipment");
Scheduler.OnRequestTrasferAction += OnTransferRequest;
Scheduler.OnTrasferActionCompleted += OnTransferDone;
}

// Score: return -1 if unavailable, >= 0 if available (higher = higher priority)
[Location("LP1", Direction.Out)]
public int LP1() => lpReady ? 0 : -1;

[Location("Stage1", Direction.In)]
public int Stage1() => stageReady ? 0 : -1;

[Location("Stage2", Direction.In)]
public int Stage2() => stage2Ready ? 0 : -1;

[Arm("Upper", Direction.Unknown)]
public int UpperArm() => upperBusy ? 1 : -1;

[Arm("Lower", Direction.Unknown)]
public int LowerArm() => lowerBusy ? 1 : -1;

private void OnTransferRequest(TransferActionArgs args)
{
// Equipment performs the physical action
Console.WriteLine($"[{args.TXID}] {args.Actiontype}{args.Target} ({args.SubstarteKey})");
// After completion, signal back:
Scheduler.TransferCompleted(new Entry { Value = args.Target });
}

private void OnTransferDone(TransferActionArgs args)
{
Console.WriteLine($"[{args.TXID}] Done: {args.Actiontype} at {args.Target}");
}
}

2. Register and run

Port.Add<TransferController, TransferModel>("Transfer");
Port.Run();

3. Register a lot and execute

// Define substrates with routing: LP1 → Stage1 → Stage2 → LP1
var substrates = new[]
{
new Substrate("W1", new SingleSlotRoute("LP1"), new ProcessRoute("Stage1", "Recipe_A"), new SingleSlotRoute("LP1")),
new Substrate("W2", new SingleSlotRoute("LP1"), new ProcessRoute("Stage1", "Recipe_A"), new SingleSlotRoute("LP1")),
};

Scheduler.Register("LOT-001", substrates);
Scheduler.Execute("LOT-001");

// Poll completion
while (!Scheduler.IsCompleted("LOT-001"))
await Task.Delay(500);

Console.WriteLine("LOT-001 transfer complete");

Substrate Routing

Each Substrate is constructed with an ordered list of Route objects describing where it must travel.

Route types

TypeDescription
SingleSlotRoute(location)Single-slot destination (e.g., Load Port, output buffer)
MultiSlotRoute(location, slotNo)Specific slot in a multi-slot location (e.g., LP cassette slot 3)
ProcessRoute(location, recipe…)Processing station — triggers recipe via Port.Set when reached
MultiSlotProcessRoute(location, recipe…)Combines slot selection with recipe execution
// Simple route: LP1 → Stage1 → back to LP1
new Substrate("W1",
new SingleSlotRoute("LP1"),
new ProcessRoute("Stage1", "Recipe_A"),
new SingleSlotRoute("LP1"));

// Multi-slot: cassette slot 3 → process → cassette slot 3
new Substrate("W3",
new MultiSlotRoute("LP1", 3),
new ProcessRoute("Stage1", "Recipe_A"),
new MultiSlotRoute("LP1", 3));

Transfer Completion

After the physical robot completes an action, call TransferCompleted to unblock the scheduler:

// Using Entry (value is the location name)
Scheduler.TransferCompleted(locationEntry);

// Using location name directly
Scheduler.TransferCompleted("Stage1");

The scheduler waits up to 30 seconds per step. If TransferCompleted is not called within that window, a timeout exception is raised and the lot execution stops.


API Reference

ISchedulerHandler methods

MethodReturnsDescription
Register(lotid, substrates…)boolRegister a lot with its substrate list for scheduling
Execute(lotid)boolStart (or restart) transfer execution for the given lot
IsCompleted(lotid)booltrue when all steps for the lot have finished
TransferCompleted(location)Signal that the equipment completed the current transfer step
SetLogger(rootPath)Enable file logging under {rootPath}\Scheduler\

Attributes

AttributeTargetDescription
[TransferHandler]PropertyInjects the ISchedulerHandler singleton
[Location(name, direction)]MethodDeclares a named transfer location; return value = availability score
[Arm(name, direction)]MethodDeclares a robot arm; return value = availability score (-1 = free)

TransferActionArgs

Passed to OnRequestTrasferAction and OnTrasferActionCompleted:

FieldTypeDescription
TXIDstringUnique transaction ID for this transfer step
ActiontypeTransferActionTypeThe action to perform (see below)
TargetstringLocation name where the action occurs
SubstarteKeystringKey of the substrate being transferred

TransferActionType enum

ValueDescription
MoveRobot arm moves to a location (no pick/place)
UpperGetUpper arm picks up a substrate
UpperPutUpper arm places a substrate
LowerGetLower arm picks up a substrate
LowerPutLower arm places a substrate

Direction enum

ValueDescription
UnknownDirection not determined (typical for arms)
InSubstrate moves into the location (pick)
OutSubstrate moves out of the location (place)

SEMI E90 Substrate States

SubstrateStatus tracks each substrate through the SEMI E90 state model:

None → AtSource → Queued → Selected → InTransfer → AtDestination

NeedsProcessing → InProcess → Processed → Completed
│ │
Rejected │

Any state → Aborted / Lost / Stopped / Skipped
StatusDescription
NoneNot yet registered
AtSourceAt source location, awaiting scheduling
QueuedEnqueued by the scheduler
SelectedSelected for the next transfer
InTransferCurrently being transported
AtDestinationArrived at destination
NeedsProcessingAt a process station, awaiting recipe
InProcessRecipe executing
ProcessedProcessing complete
CompletedAll route steps done
RejectedRejected during processing
AbortedTransfer aborted by operator or system
LostLocation unknown
StoppedPaused, may be resumed
SkippedIntentionally skipped in the sequence

Events

OnRequestTrasferAction

Raised when the scheduler needs the equipment to perform a transfer step. The handler must call Scheduler.TransferCompleted(…) when the physical action is complete.

Scheduler.OnRequestTrasferAction += (TransferActionArgs args) =>
{
switch (args.Actiontype)
{
case TransferActionType.UpperGet:
Robot.Pick("Upper", args.Target);
break;
case TransferActionType.UpperPut:
Robot.Place("Upper", args.Target);
break;
case TransferActionType.Move:
Robot.MoveTo(args.Target);
Scheduler.TransferCompleted(args.Target); // Move steps complete immediately
break;
}
};

OnTrasferActionCompleted

Raised after the scheduler acknowledges that a transfer step is complete (after TransferCompleted is called).

Scheduler.OnTrasferActionCompleted += (TransferActionArgs args) =>
{
Console.WriteLine($"[{args.TXID}] Completed: {args.Actiontype} at {args.Target}");
};

Logging

[Preset]
public void Preset()
{
Scheduler.SetLogger(@"C:\Logs\Equipment");
// Creates: C:\Logs\Equipment\Scheduler\
}

Log files are created and rotated by the Rust backend. Entries include TXID, action type, target location, and timestamps.


  • FlowHandler — Step-based workflow engine used to implement individual transfer actions
  • attribute — Full attribute reference ([Controller], [Preset], [ModelBinding], etc.)
  • SECS/GEM — SEMI E90 substrate state integration