UnderAutomation
질문이요?

[email protected]

문의하기
UnderAutomation
⌘Q
ABB SDK documentation
Control panel & operation mode
Documentation home

RAPID tasks & program execution

List RAPID tasks, start and stop program execution, follow the execution state, move the program pointer, load and unload modules.

robot.Rws.Rapid is the service of the program the robot runs. This page covers the tasks the program is split into, starting and stopping the execution, and moving the program pointer. The variables of the program are on RAPID variables & symbols, the source of the modules on RAPID modules & program files.

Reading never needs anything special. Every write of this page needs the Rapid mastership, and most of them also need the controller to be in the right operation mode. None of these resources answers while the controller runs in boot mode.

Tasks

A controller runs one RAPID task per robot, plus the background tasks the system needs. GetTasks lists them all, GetTask returns everything the controller knows about one of them.

// Every RAPID task of the controller
foreach (RapidTaskItem task in robot.Rws.Rapid.GetTasks())
{
Console.WriteLine(task.Name); // T_ROB1
Console.WriteLine(task.Type); // Normal, Static or SemiStatic
Console.WriteLine(task.TaskState); // Linked when the program is ready to run
Console.WriteLine(task.ExecutionState); // Started, Stopped, Ready
Console.WriteLine(task.Active); // null when the controller did not report it
Console.WriteLine(task.MotionTask); // true for the task that drives the robot
}
// Everything the controller knows about one task
RapidTaskInfo info = robot.Rws.Rapid.GetTask("T_ROB1");
Console.WriteLine(info.ExecutionLevel); // Normal, Trap, User, None
Console.WriteLine(info.ExecutionCycle); // Forever, Once, OnceDone
Console.WriteLine(info.ExecutionMode); // Continuous, StepIn, StepOver, ...
Console.WriteLine(info.ProductionEntryPoint);
Console.WriteLine(info.Trust);
RapidTaskTypeWhat the task is
NormalA task holding a program an operator starts and stops
StaticA task started with the controller and never stopped
SemiStaticA task started with the controller and restarted at every program reset
UnknownThe controller reported a type the SDK does not know

TaskState says whether the task can run. Only Linked means that the modules of the task were turned into a runnable program. Empty means the task holds nothing, Loaded that the modules are there but not linked yet.

RapidTaskExecutionStateMeaning
ReadyThe task is ready to run but is not running
StartedThe task is running
StoppedThe task was stopped before its end
UninitializedThe task is not usable yet

Activate and deactivate a task

A deactivated task is not started when the program starts. The selection panel of the FlexPendant shows the same thing, GetTaskSelection reads it. UserModify says whether an operator is allowed to change the selection of that task from the pendant.

// Which tasks the operator panel has selected, and which of them an operator may change
foreach (RapidTaskSelectionItem item in robot.Rws.Rapid.GetTaskSelection())
{
Console.WriteLine(item.Name + " selected=" + item.Selected + " userModify=" + item.UserModify);
}
// Activating or deactivating a task is a write, so it needs the mastership
robot.Rws.Mastership.Request(MastershipDomain.Rapid);
try
{
robot.Rws.Rapid.ActivateTask("T_ROB1");
robot.Rws.Rapid.DeactivateTask("T_ROB2");
// Same thing for every task at once
robot.Rws.Rapid.ActivateTasks();
robot.Rws.Rapid.DeactivateTasks();
}
finally
{
robot.Rws.Mastership.Release(MastershipDomain.Rapid);
}

GetTaskProgramPointerSyncState and GetTaskMotionPointerSyncState, listed below, are described in the program pointer section of this page.

Methods of RapidService :
// Activates one task (synchronous)
void ActivateTask(string task);
// Activates every task of the controller (synchronous)
void ActivateTasks();
// Deactivates one task (synchronous)
void DeactivateTask(string task);
// Deactivates every task of the controller (synchronous)
void DeactivateTasks();
// Gets everything the controller reports about one task (synchronous)
RapidTaskInfo GetTask(string task);
// Gets whether the motion pointer of one task is synchronized with the others (synchronous)
RapidPointerSyncState GetTaskMotionPointerSyncState(string task);
// Gets whether the program pointer of one task is synchronized with the others (synchronous)
RapidPointerSyncState GetTaskProgramPointerSyncState(string task);
// Gets the task selection panel: which tasks are selected, and which of them an operator is allowed to change the selection of (synchronous)
RapidTaskSelectionItem[] GetTaskSelection();
// Gets every RAPID task of the controller and what each of them is doing (synchronous)
RapidTaskItem[] GetTasks();

Every method also exists in an asynchronous version, with the same name followed by Async and an optional CancellationToken.

Members of Rws.Data.RapidTaskItem :
public class RapidTaskItem {
// Initializes a new instance of the <xref href="UnderAutomation.ABB.Rws.Data.RapidTaskItem" data-throw-if-not-resolved="false"></xref> class
public RapidTaskItem()
// Whether the task is active, null when the controller did not report it
public bool? Active { get; set; }
// Whether the task is running, and whether it could be
public RapidTaskExecutionState ExecutionState { get; set; }
// Whether the task can move a mechanical unit, null when the controller did not report it
public bool? MotionTask { get; set; }
// Name of the task, for example "T_ROB1"
public string Name { get; set; }
// How far the controller has got in preparing the program of the task
public RapidTaskState TaskState { get; set; }
// Returns a string representation of this task
public override string ToString()
// Kind of task, which decides when the controller runs it
public RapidTaskType Type { get; set; }
}
Members of Rws.Data.RapidTaskInfo :
public class RapidTaskInfo : RapidTaskItem {
// Initializes a new instance of the <xref href="UnderAutomation.ABB.Rws.Data.RapidTaskInfo" data-throw-if-not-resolved="false"></xref> class
public RapidTaskInfo()
// Whether the task is bound to a configured task number, null when the controller did not report it
public bool? BindReference { get; set; }
// Number of cycles the task is set to run.
//
// <p>Only reported over a connection established with version 2, and left to
// <xref href="UnderAutomation.ABB.Rws.Data.RapidExecutionCycle.Unknown" data-throw-if-not-resolved="false"></xref> otherwise.</p>
public RapidExecutionCycle ExecutionCycle { get; set; }
// Level at which the code of the task is currently executing
public RapidExecutionLevel ExecutionLevel { get; set; }
// Stepping mode the task was last started with
public RapidTaskExecutionMode ExecutionMode { get; set; }
// What kind of code the task is currently running
public RapidExecutionType ExecutionType { get; set; }
// Routine the program pointer moves to when it is reset, for example "main"
public string ProductionEntryPoint { get; set; }
// Identifier of the task, null when the controller did not report it
public int? TaskId { get; set; }
// Name of the task running in the foreground, empty when there is none
public string TaskInForeground { get; set; }
// What the controller does to the system when this task stops unexpectedly
public RapidTaskTrustLevel Trust { get; set; }
}
Members of Rws.Data.RapidTaskSelectionItem :
public class RapidTaskSelectionItem {
// Initializes a new instance of the <xref href="UnderAutomation.ABB.Rws.Data.RapidTaskSelectionItem" data-throw-if-not-resolved="false"></xref> class
public RapidTaskSelectionItem()
// Whether the task can move a mechanical unit, null when the controller did not report it
public bool? MotionTask { get; set; }
// Name of the task, for example "T_ROB1"
public string Name { get; set; }
// Whether the task is selected, null when the controller did not report it
public bool? Selected { get; set; }
// Returns a string representation of this task selection
public override string ToString()
// Whether an operator is allowed to change the selection of this task, null when the
// controller did not report it
public bool? UserModify { get; set; }
}
Members of Rws.Data.RapidTaskType :
public enum RapidTaskType {
// A task started and stopped together with the program
Normal = 1
// A task restarted from its beginning every time the controller starts
SemiStatic = 3
// A task that keeps its program pointer where it was when the controller was switched off
Static = 2
// The controller reported a type this library does not know
Unknown = 0
}
Members of Rws.Data.RapidTaskState :
public enum RapidTaskState {
// The task holds no program
Empty = 1
// The task has been created but its program is not linked yet
Initiated = 2
// The program of the task is linked and ready to run
Linked = 3
// A program is loaded into the task but not linked yet
Loaded = 4
// The task is not initialized
Uninitialized = 5
// The controller reported a state this library does not know
Unknown = 0
}
Members of Rws.Data.RapidTaskExecutionState :
public enum RapidTaskExecutionState {
// The task is ready to be started
Ready = 1
// The task is running
Started = 3
// The task was running and has been stopped
Stopped = 2
// The task is not initialized
Uninitialized = 4
// The controller reported a state this library does not know
Unknown = 0
}
Members of Rws.Data.RapidTaskExecutionMode :
public enum RapidTaskExecutionMode {
// The task runs without stepping
Continuous = 1
// The task steps backwards
StepBack = 5
// The task steps into the routine calls
StepIn = 3
// The task steps to the last instruction
StepLast = 6
// The task steps out of the current routine
StepOutOf = 4
// The task steps over the routine calls
StepOver = 2
// The task advances one instruction at a time
StepWise = 7
// The controller reported a mode this library does not know
Unknown = 0
}
Members of Rws.Data.RapidTaskTrustLevel :
public enum RapidTaskTrustLevel {
// The system carries on
None = 1
// The whole system fails
SystemFailure = 2
// The system halts
SystemHalt = 3
// The system stops
SystemStop = 4
// The controller reported a level this library does not know
Unknown = 0
}

Build a task

BuildTask links the modules a task holds into a runnable program. The controller accepts the request even when the program does not compile, so read GetBuildErrors afterwards and check that the task state became Linked.

robot.Rws.Mastership.Request(MastershipDomain.Rapid);
try
{
// Link the modules of the task into a runnable program
robot.Rws.Rapid.BuildTask("T_ROB1");
}
finally
{
robot.Rws.Mastership.Release(MastershipDomain.Rapid);
}
// The controller does not fail the build request, it reports what it refused afterwards
foreach (RapidBuildError error in robot.Rws.Rapid.GetBuildErrors("T_ROB1"))
{
Console.WriteLine(error.ModuleName + " " + error.Row + "," + error.Column + ": " + error.Error);
}
// The task is runnable when its state is Linked
Console.WriteLine(robot.Rws.Rapid.GetTask("T_ROB1").TaskState);

The build errors are described in RAPID modules & program files.

Methods of RapidService :
// Links the program of a task, which is what turns the modules it holds into something runnable (synchronous) Read GetBuildErrors() afterwards to find out what the controller refused.
void BuildTask(string task);

Every method also exists in an asynchronous version, with the same name followed by Async and an optional CancellationToken.

Load a module

AVAILABLE ON
RWS 1.0
RWS 2.0
Only an OmniCore answers with the name of the module that was loaded, an IRC5 returns null.

LoadModule loads one module file into a task. The file has to be on the file system of the controller already, so upload it first with the file system service. Set replace to true when a module of the same name is already loaded, otherwise the controller refuses the request.

robot.Rws.Mastership.Request(MastershipDomain.Rapid);
try
{
// The file has to be on the controller already. Upload it first with robot.Rws.File.
// On OmniCore the call answers the name of what was loaded, on IRC5 it answers null.
string loaded = robot.Rws.Rapid.LoadModule("T_ROB1", "$HOME/mymodule.mod", true);
Console.WriteLine(loaded);
robot.Rws.Rapid.UnloadModule("T_ROB1", "mymodule");
}
finally
{
robot.Rws.Mastership.Release(MastershipDomain.Rapid);
}

UnloadModule takes the name of the module, not the name of the file. A module that was never saved is lost when it is unloaded.

Loading a whole program instead of one module is done with LoadProgram, see RAPID modules & program files.

Methods of RapidService :
// Loads a module file into a task (synchronous)
string LoadModule(string task, string modulePath, bool replace = false);
// Unloads a module from a task (synchronous)
void UnloadModule(string task, string module);

Every method also exists in an asynchronous version, with the same name followed by Async and an optional CancellationToken.

Start and stop the program

Starting a program from your application fails when one of these conditions is not met:

  1. The controller is in automatic mode, or in manual mode with the enabling device held. The mode is read with the control panel service.
  2. The motors are on, Panel.SetControllerState(ControllerState.MotorsOn).
  3. The task is active and its state is Linked.
  4. The program pointer is set, which ResetProgramPointer does for every task.
  5. Your connection holds the Rapid mastership.
// 1. The controller has to be in automatic mode
if (robot.Rws.Panel.GetOperationMode() != OperationMode.Automatic)
throw new Exception("Turn the key of the controller to automatic mode");
robot.Rws.Mastership.Request(MastershipDomain.Rapid);
try
{
// 2. Motors on
robot.Rws.Panel.SetControllerState(ControllerState.MotorsOn);
// 3. Program pointer back to the entry point of every task
robot.Rws.Rapid.ResetProgramPointer();
// 4. Start
robot.Rws.Rapid.Start(RapidRegainMode.Continue,
RapidExecutionMode.Continue,
RapidExecutionCycle.Forever,
RapidStartCondition.None,
false, // do not stop at breakpoints
false); // normal tasks only
}
finally
{
robot.Rws.Mastership.Release(MastershipDomain.Rapid);
}
// 5. Check that it really started, the call above only means the request was accepted
RapidExecutionInfo execution = robot.Rws.Rapid.GetExecutionState();
Console.WriteLine(execution.State); // Running or Stopped
Console.WriteLine(execution.Cycle); // Forever, Once, OnceDone

Start returns as soon as the controller accepts the request, not when the robot moves. Read GetExecutionState afterwards to know what really happened.

RapidRegainModeWhat the robot does when execution resumes
ContinueResume from the current position, without going back to the path
RegainMove back onto the path first
ClearDrop the path and resume from the current position
EnterConsumeResume by entering the path already computed
RapidExecutionModeHow far the program advances
ContinueRun until something stops it
StepInEnter the routine called by the current instruction
StepOverRun the current instruction whole, without entering the routine it calls
StepOutRun until the current routine returns
StepBackStep one instruction backwards
StepLastStep to the last instruction
StepMotionStep to the next motion instruction

RapidStartCondition.CallChain asks the controller to start only when the call chain of the program pointer is still valid, which is a way to refuse a start after the source was edited.

Cycles and entry point

SetExecutionCycle takes Once or Forever, the other values of the enum are only reported by the controller. StartFromProductionEntry starts at the production entry point of the task instead of the current program pointer.

AbortExecutionLevel leaves the routine running now and goes back to the level under it. This is how a trap or a service routine started by hand is abandoned without stopping the program below it.

robot.Rws.Mastership.Request(MastershipDomain.Rapid);
try
{
// Only Once and Forever are accepted here
robot.Rws.Rapid.SetExecutionCycle(RapidExecutionCycle.Once);
// Start from the production entry point instead of the current program pointer
robot.Rws.Rapid.StartFromProductionEntry();
// Leave the routine that is running now and go back to the level below it.
// This is how a trap or a service routine is abandoned without stopping the program under it.
robot.Rws.Rapid.AbortExecutionLevel("T_ROB1");
}
finally
{
robot.Rws.Mastership.Release(MastershipDomain.Rapid);
}

Stop

// Stop at the end of the current instruction, normal tasks only
robot.Rws.Rapid.Stop(RapidStopMode.Stop, RapidTaskScope.Normal);
// Let the robot finish the cycle it is in, then stop
robot.Rws.Rapid.Stop(RapidStopMode.Cycle, RapidTaskScope.Normal);
// Stop everything at once, including the static and semi static tasks
robot.Rws.Rapid.Stop(RapidStopMode.QuickStop, RapidTaskScope.AllTasks);
// Wait until the controller confirms the program is stopped
while (robot.Rws.Rapid.GetExecutionState().State != RapidExecutionState.Stopped)
System.Threading.Thread.Sleep(200);
RapidStopModeHow the program stops
CycleAt the end of the current cycle
InstructionAt the end of the current instruction
StopAs soon as the robot can decelerate along its path
QuickStopAs fast as the robot can, leaving the path

RapidTaskScope.Normal stops the normal tasks only, AllTasks also stops the static and semi static ones. Stop returns before the robot has stopped, so wait until GetExecutionState reports Stopped.

Hold-to-run

In manual mode the program only runs while a client keeps saying that the hold-to-run control is held. Send Press, then Held about every two seconds. The controller stops the program as soon as it stops hearing from your application.

// Manual mode only. Press, then keep sending Held, the controller stops the
// program as soon as it stops hearing from your application.
robot.Rws.Rapid.SetHoldToRun(RapidHoldToRunState.Press);
robot.Rws.Rapid.Start(RapidRegainMode.Continue, RapidExecutionMode.Continue);
for (int i = 0; i < 10; i++)
{
robot.Rws.Rapid.SetHoldToRun(RapidHoldToRunState.Held);
System.Threading.Thread.Sleep(1000);
}
robot.Rws.Rapid.SetHoldToRun(RapidHoldToRunState.Release);

This is only honoured by a virtual controller, and only for a client the controller considers local. A real cabinet expects the physical device.

A complete example, with the checks around it, is given in Start & stop a RAPID program.

Methods of RapidService :
// Abandons the routine the task is currently running and returns to the level below it (synchronous) This is how a trap or a service routine started by hand is left without stopping the program underneath it.
void AbortExecutionLevel(string task);
// Gets whether the controller is executing RAPID code, and how many cycles it is set to run (synchronous)
RapidExecutionInfo GetExecutionState();
// Moves the program pointer of every task back to the entry point of its program (synchronous)
void ResetProgramPointer();
// Sets how many times the program runs before stopping (synchronous)
void SetExecutionCycle(RapidExecutionCycle cycle);
// Drives the hold-to-run control that lets the program run in manual mode (synchronous) Send RapidHoldToRunState.Press to allow execution to start, then RapidHoldToRunState.Held about every two seconds to keep it running; the controller stops the program as soon as it stops hearing from the client. Send RapidHoldToRunState.Release to stop it at once.
void SetHoldToRun(RapidHoldToRunState state);
// Starts executing the RAPID program from where the program pointer stands (synchronous) The controller has to be in automatic mode with the motors on, or in manual mode with the enabling device held. Reset the program pointer first with RapidService.ResetProgramPointer to start from the beginning.
void Start(RapidRegainMode regain = RapidRegainMode.Continue, RapidExecutionMode executionMode = RapidExecutionMode.Continue, RapidExecutionCycle cycle = RapidExecutionCycle.Forever, RapidStartCondition condition = RapidStartCondition.None, bool stopAtBreakpoint = false, bool allTasksBySelection = false);
// Starts executing from the production entry point of the program rather than from where the program pointer stands (synchronous)
void StartFromProductionEntry();
// Starts recording the RAPID execution trace into a file (synchronous) The trace names every instruction the controller runs, which is what it takes to find out why a program took a branch it should not have.
void StartSpy(string logFile);
// Stops the RAPID execution (synchronous)
void Stop(RapidStopMode stopMode = RapidStopMode.Stop, RapidTaskScope scope = RapidTaskScope.Normal);
// Stops recording the RAPID execution trace (synchronous)
void StopSpy();

Every method also exists in an asynchronous version, with the same name followed by Async and an optional CancellationToken.

Members of Rws.Data.RapidExecutionInfo :
public class RapidExecutionInfo {
// Initializes a new instance of the <xref href="UnderAutomation.ABB.Rws.Data.RapidExecutionInfo" data-throw-if-not-resolved="false"></xref> class
public RapidExecutionInfo()
// Number of cycles the program is set to run
public RapidExecutionCycle Cycle { get; set; }
// Whether RAPID code is currently running
public RapidExecutionState State { get; set; }
// Returns a string representation of this execution state
public override string ToString()
}
Members of Rws.Data.RapidExecutionState :
public enum RapidExecutionState {
// RAPID execution is running
Running = 1
// RAPID execution is stopped
Stopped = 2
// The controller reported a state this library does not know
Unknown = 0
}
Members of Rws.Data.RapidExecutionCycle :
public enum RapidExecutionCycle {
// The cycle currently configured is left untouched
AsIs = 2
// The program runs again every time it reaches its end
Forever = 1
// The program runs once and stops at its end
Once = 3
// The program was asked to run once and has finished doing so
OnceDone = 4
// The controller reported a cycle this library does not know
Unknown = 0
}
Members of Rws.Data.RapidExecutionMode :
public enum RapidExecutionMode {
// Run until something stops it
Continue = 0
// Step one instruction backwards
StepBack = 4
// Step into the routine called by the current instruction
StepIn = 1
// Step to the last instruction
StepLast = 5
// Step to the next motion instruction
StepMotion = 6
// Run until the current routine returns
StepOut = 3
// Run the current instruction whole, without entering the routine it calls
StepOver = 2
}
Members of Rws.Data.RapidRegainMode :
public enum RapidRegainMode {
// Drop the path and resume from the current position
Clear = 2
// Resume from the current position without moving back to the path
Continue = 0
// Resume by entering the consumption of the already generated path
EnterConsume = 3
// Move back onto the path before resuming
Regain = 1
}
Members of Rws.Data.RapidStopMode :
public enum RapidStopMode {
// Stop when the current cycle ends
Cycle = 0
// Stop when the current instruction ends
Instruction = 1
// Stop as fast as the robot can, leaving the path
QuickStop = 3
// Stop as soon as the robot can decelerate along its path
Stop = 2
}
Members of Rws.Data.RapidStartCondition :
public enum RapidStartCondition {
// Start only when the call chain of the program pointer is still valid
CallChain = 1
// Start without any additional check
None = 0
}
Members of Rws.Data.RapidTaskScope :
public enum RapidTaskScope {
// Apply to every task of the system
AllTasks = 1
// Apply to the tasks the task selection panel has enabled
Normal = 0
}
Members of Rws.Data.RapidHoldToRunState :
public enum RapidHoldToRunState {
// Confirm that execution may keep running, which has to be repeated about every two seconds
Held = 1
// Ask for execution to be allowed to start
Press = 0
// Stop execution immediately
Release = 2
}

Execution trace

The controller can write every instruction it runs into a file. It is the fastest way to find out why a program took a branch it should not have. The two calls take the mastership by themselves, your code does not have to.

// The trace names every instruction the controller runs. No mastership needed,
// the controller takes it by itself for these two calls.
robot.Rws.Rapid.StartSpy("$HOME/trace.log");
Console.WriteLine(robot.Rws.Rapid.GetSpyStatus()); // Logging or NotLogging
System.Threading.Thread.Sleep(5000);
robot.Rws.Rapid.StopSpy();
// Then download the file with the file service
string trace = robot.Rws.File.GetFileAsText("$HOME/trace.log");
Console.WriteLine(trace);

The file is written on the controller, download it afterwards with the file system service. A trace grows fast, do not leave it running.

Execution trace of RapidService :
// Gets whether the controller is recording the RAPID execution trace to a file (synchronous)
RapidSpyStatus GetSpyStatus();

Every method also exists in an asynchronous version, with the same name followed by Async and an optional CancellationToken.

Members of Rws.Data.RapidSpyStatus :
public enum RapidSpyStatus {
// The execution trace is being written
Logging = 1
// No execution trace is being written
NotLogging = 2
// The controller reported a status this library does not know
Unknown = 0
}

Program pointer and motion pointer

Each task has two pointers. The program pointer says which instruction runs next, the motion pointer which one the robot is really executing. They drift apart because the controller plans the path ahead of the movement.

// Where the two pointers of the task stand
RapidPointers pointers = robot.Rws.Rapid.GetPointers("T_ROB1");
if (pointers.ProgramPointer.Available)
{
Console.WriteLine(pointers.ProgramPointer.Module + "/" + pointers.ProgramPointer.Routine);
Console.WriteLine(pointers.ProgramPointer.BeginRow + "," + pointers.ProgramPointer.BeginColumn);
}
// The motion pointer is behind the program pointer, the controller plans the path
// ahead of the movement. It is not available in a task that has not moved yet.
Console.WriteLine(pointers.MotionPointer.Available);
// The piece of source the program pointer covers. The controller refuses the request
// when the task has no program pointer, reset it or start the program first.
RapidProgramCounterPosition position = robot.Rws.Rapid.GetProgramCounterPosition("T_ROB1");
Console.WriteLine(position.Module + " " + position.StartLine + "," + position.StartColumn);
// Moving the pointer is a write, it needs the RAPID mastership
robot.Rws.Mastership.Request(MastershipDomain.Rapid);
try
{
// To the beginning of a routine. The module name is used by an IRC5 only,
// an OmniCore looks the routine up in the whole task.
robot.Rws.Rapid.SetProgramPointerToRoutine("T_ROB1", "MainModule", "main");
// To a service routine, which has to be entered at user level
robot.Rws.Rapid.SetProgramPointerToRoutineUrl("T_ROB1", "RAPID/T_ROB1/BASEFUN/LoadIdentify", true);
// To one position of the source. The routine name is used by an IRC5 only,
// an OmniCore works it out from the position itself.
robot.Rws.Rapid.SetProgramPointerToCursor("T_ROB1", "MainModule", "main", 12, 1);
// One instruction forward or backward, automatic mode only
robot.Rws.Rapid.SetProgramPointerToNextInstruction("T_ROB1");
robot.Rws.Rapid.SetProgramPointerToPreviousInstruction("T_ROB1");
}
finally
{
robot.Rws.Mastership.Release(MastershipDomain.Rapid);
}
AVAILABLE ON
RWS 1.0
RWS 2.0
An IRC5 needs the module and the routine name, an OmniCore works them out from the position alone.

SetProgramPointerToRoutine takes a module name and SetProgramPointerToCursor a routine name. An IRC5 refuses the request without them, an OmniCore ignores them and finds the routine by itself. Pass them in both cases, your code then works on the two generations.

A few things to know before moving the pointer:

  • Moving the pointer needs the Rapid mastership, and the program has to be stopped.
  • SetProgramPointerToNextInstruction and SetProgramPointerToPreviousInstruction are refused outside automatic mode.
  • A service routine has to be entered at user level, so pass true for userLevel. GetServiceRoutines gives the paths SetProgramPointerToRoutineUrl takes.
  • GetProgramCounterPosition is refused when the task has no program pointer at all. Reset it or start the program first.
  • GetProgram returns the name of the program the task holds and the routine ResetProgramPointer goes back to.

Synchronization and change counters

GetProgramPointerSyncState and GetMotionPointerSyncState say whether the pointers of the tasks are synchronized with each other, for the whole controller or for one task. GetStructuralChangeCount returns two counters that only move when something changed in the task, which is cheaper than downloading the modules again to find out that nothing moved.

// For the whole controller
RapidPointerSyncState program = robot.Rws.Rapid.GetProgramPointerSyncState();
RapidPointerSyncState motion = robot.Rws.Rapid.GetMotionPointerSyncState();
Console.WriteLine(program + " / " + motion); // On or Off
// For one task
Console.WriteLine(robot.Rws.Rapid.GetTaskProgramPointerSyncState("T_ROB1"));
Console.WriteLine(robot.Rws.Rapid.GetTaskMotionPointerSyncState("T_ROB1"));
// Two counters that say whether anything changed in the task, cheaper than
// downloading the modules again to find out that nothing moved
RapidStructuralChangeCount counters = robot.Rws.Rapid.GetStructuralChangeCount("T_ROB1");
Console.WriteLine(counters.ChangeCount);
Console.WriteLine(counters.StructuralChangeCount);
Methods of RapidService :
// Gets whether the motion pointers of every task are synchronized with each other (synchronous)
RapidPointerSyncState GetMotionPointerSyncState();
// Gets where the program pointer and the motion pointer of a task stand (synchronous) The program pointer says which instruction runs next, the motion pointer which one the robot is actually executing; they drift apart because the controller plans the path ahead of the movement.
RapidPointers GetPointers(string task);
// Gets the program loaded into a task (synchronous)
RapidProgramInfo GetProgram(string task);
// Gets which piece of source the program pointer of a task points at (synchronous)
RapidProgramCounterPosition GetProgramCounterPosition(string task);
// Gets whether the program pointers of every task are synchronized with each other (synchronous)
RapidPointerSyncState GetProgramPointerSyncState();
// Gets the two counters a task keeps of what has changed in it (synchronous) Comparing them with what a previous reading gave is cheaper than fetching the modules again to find out that nothing moved.
RapidStructuralChangeCount GetStructuralChangeCount(string task);
// Moves the program pointer of a task to a position of a module (synchronous)
void SetProgramPointerToCursor(string task, string module, string routine, int row, int column);
// Moves the program pointer of a task forward by one instruction (synchronous)
void SetProgramPointerToNextInstruction(string task);
// Moves the program pointer of a task back by one instruction (synchronous)
void SetProgramPointerToPreviousInstruction(string task);
// Moves the program pointer of a task to the beginning of a routine (synchronous)
void SetProgramPointerToRoutine(string task, string module, string routine, bool userLevel = false);
// Moves the program pointer of a task to a routine named by its path (synchronous) This is what the paths GetServiceRoutines() reports are for.
void SetProgramPointerToRoutineUrl(string task, string routineUrl, bool userLevel = false);

Every method also exists in an asynchronous version, with the same name followed by Async and an optional CancellationToken.

Members of Rws.Data.RapidPointers :
public class RapidPointers {
// Initializes a new instance of the <xref href="UnderAutomation.ABB.Rws.Data.RapidPointers" data-throw-if-not-resolved="false"></xref> class
public RapidPointers()
// Instruction the robot is currently moving for
public RapidPointerPosition MotionPointer { get; set; }
// Instruction the task will execute next
public RapidPointerPosition ProgramPointer { get; set; }
// Returns a string representation of the two pointers
public override string ToString()
}
Members of Rws.Data.RapidPointerPosition :
public class RapidPointerPosition {
// Initializes a new instance of the <xref href="UnderAutomation.ABB.Rws.Data.RapidPointerPosition" data-throw-if-not-resolved="false"></xref> class
public RapidPointerPosition()
// Whether the controller reported a position for this pointer at all
public bool Available { get; set; }
// Column the pointer begins at, null when the controller did not report it
public int? BeginColumn { get; set; }
// Line the pointer begins at, null when the controller did not report it
public int? BeginRow { get; set; }
// How many times the pointer has been moved, null when the controller did not report it
public int? ChangeCount { get; set; }
// Column the pointer ends at, null when the controller did not report it
public int? EndColumn { get; set; }
// Line the pointer ends at, null when the controller did not report it
public int? EndRow { get; set; }
// What kind of code the pointer is standing in
public RapidExecutionType ExecutionType { get; set; }
// Name of the module the pointer stands in
public string Module { get; set; }
// Name of the routine the pointer stands in
public string Routine { get; set; }
// Returns a string representation of this pointer position
public override string ToString()
}
Members of Rws.Data.RapidProgramCounterPosition :
public class RapidProgramCounterPosition {
// Initializes a new instance of the <xref href="UnderAutomation.ABB.Rws.Data.RapidProgramCounterPosition" data-throw-if-not-resolved="false"></xref> class
public RapidProgramCounterPosition()
// Column the pointed instruction ends at, null when the controller did not report it
public int? EndColumn { get; set; }
// Line the pointed instruction ends at, null when the controller did not report it
public int? EndLine { get; set; }
// Name of the module the pointer stands in
public string Module { get; set; }
// Name of the routine the pointer stands in
public string Routine { get; set; }
// Column the pointed instruction starts at, null when the controller did not report it
public int? StartColumn { get; set; }
// Line the pointed instruction starts at, null when the controller did not report it
public int? StartLine { get; set; }
// Returns a string representation of this position
public override string ToString()
}
Members of Rws.Data.RapidPointerSyncState :
public enum RapidPointerSyncState {
// The pointers are not synchronized
Off = 2
// The pointers are synchronized
On = 1
// The controller reported a state this library does not know
Unknown = 0
}
Members of Rws.Data.RapidStructuralChangeCount :
public class RapidStructuralChangeCount {
// Initializes a new instance of the <xref href="UnderAutomation.ABB.Rws.Data.RapidStructuralChangeCount" data-throw-if-not-resolved="false"></xref> class
public RapidStructuralChangeCount()
// Counter the controller increments whenever anything relevant changes in the task
public int? ChangeCount { get; set; }
// Counter the controller increments when a module is loaded, unloaded or renamed.
//
// <p>A rename counts as an unload followed by a load.</p>
public int? StructuralChangeCount { get; set; }
// Returns a string representation of these counters
public override string ToString()
}
Members of Rws.Data.RapidExecutionType :
public enum RapidExecutionType {
// An event routine is running
EventRoutine = 6
// An external interrupt is running
ExternalInterrupt = 4
// An interrupt is running
Interrupt = 3
// Nothing is running
None = 1
// The normal program is running
Normal = 2
// The controller reported a type this library does not know
Unknown = 0
// A user routine is running
UserRoutine = 5
}

Call stack

GetActivationRecord reads one frame of the call stack. Frame 1 holds the program pointer, and the number grows towards the entry point of the program. The controller refuses the request when the task has no program pointer, or when the stack is not that deep.

// Frame 1 is the one holding the program pointer, the number grows towards the entry point
for (int frame = 1; frame <= 5; frame++)
{
RapidActivationRecord record = robot.Rws.Rapid.GetActivationRecord("T_ROB1", frame);
Console.WriteLine(record.RoutineUrl);
Console.WriteLine(record.BeginRow + "," + record.BeginColumn);
Console.WriteLine(record.ExecutionLevel);
}
// The routines the program pointer may be moved to, service routines included
foreach (RapidServiceRoutineItem routine in robot.Rws.Rapid.GetServiceRoutines("T_ROB1"))
{
Console.WriteLine(routine.Name + " -> " + routine.Url + " service=" + routine.IsServiceRoutine);
}
RapidExecutionLevelWhere execution stands
NormalIn the program itself
TrapIn a trap routine
UserIn a routine started by hand, such as a service routine
NoneNothing is running at this level
UnknownThe controller reported a level the SDK does not know
Methods of RapidService :
// Gets one frame of the call stack of a task: which routine is running and where execution stands in it (synchronous)
RapidActivationRecord GetActivationRecord(string task, int stackFrame = 1);
// Gets the routines of a task the program pointer can be moved to (synchronous)
RapidServiceRoutineItem[] GetServiceRoutines(string task, int? start = null, int? limit = null);

Every method also exists in an asynchronous version, with the same name followed by Async and an optional CancellationToken.

Members of Rws.Data.RapidActivationRecord :
public class RapidActivationRecord {
// Initializes a new instance of the <xref href="UnderAutomation.ABB.Rws.Data.RapidActivationRecord" data-throw-if-not-resolved="false"></xref> class
public RapidActivationRecord()
// Column the executing statement starts at, null when the controller did not report it
public int? BeginColumn { get; set; }
// Line the executing statement starts at, null when the controller did not report it
public int? BeginRow { get; set; }
// Column the executing statement ends at, null when the controller did not report it
public int? EndColumn { get; set; }
// Line the executing statement ends at, null when the controller did not report it
public int? EndRow { get; set; }
// Level at which this frame is executing
public RapidExecutionLevel ExecutionLevel { get; set; }
// Path of the routine this frame is executing
public string RoutineUrl { get; set; }
// Path identifying this stack frame, which the UI instruction resources also take
public string StackUrl { get; set; }
// Returns a string representation of this stack frame
public override string ToString()
}
Members of Rws.Data.RapidServiceRoutineItem :
public class RapidServiceRoutineItem {
// Initializes a new instance of the <xref href="UnderAutomation.ABB.Rws.Data.RapidServiceRoutineItem" data-throw-if-not-resolved="false"></xref> class
public RapidServiceRoutineItem()
// Whether this is a service routine rather than an ordinary one, null when the controller
// did not report it
public bool? IsServiceRoutine { get; set; }
// Name of the routine, for example "LoadIdentify"
public string Name { get; set; }
// Returns a string representation of this routine
public override string ToString()
// Path of the routine, which <code>RapidService.SetProgramPointerToRoutineUrl()</code> takes
public string Url { get; set; }
}
Members of Rws.Data.RapidExecutionLevel :
public enum RapidExecutionLevel {
// Nothing is executing
None = 1
// The normal user code is executing
Normal = 2
// A trap routine is executing
Trap = 3
// The controller reported a level this library does not know
Unknown = 0
// A user routine is executing
User = 4
}

Answer an operator dialogue

A RAPID program can stop and ask the operator something. The controller then reports one pending instruction, and the program waits until it is answered. GetActiveUiInstruction returns null when nothing is pending.

// Null when the program is not asking the operator for anything right now
RapidUiInstruction question = robot.Rws.Rapid.GetActiveUiInstruction();
if (question != null)
{
Console.WriteLine(question.Instruction); // name of the RAPID instruction waiting
Console.WriteLine(question.Message);
Console.WriteLine(question.Event); // Send, Post or Abort
// What the program passed in, and what it is waiting for. The names of the
// parameters depend on the instruction, so read them before writing one.
foreach (RapidUiInstructionParameter parameter in
robot.Rws.Rapid.GetUiInstructionParameters(question.StackUrl))
{
Console.WriteLine(parameter.Name + " = " + parameter.Value);
}
// Answering is a write, so it needs the mastership
robot.Rws.Mastership.Request(MastershipDomain.Rapid);
try
{
// Write the parameter carrying the answer, then the one marking it as completed
robot.Rws.Rapid.SetUiInstructionParameter(question.StackUrl, "TPCompleted", "TRUE");
}
finally
{
robot.Rws.Mastership.Release(MastershipDomain.Rapid);
}
Console.WriteLine(robot.Rws.Rapid.GetUiInstructionParameter(question.StackUrl, "TPCompleted"));
}

The names of the parameters depend on the instruction the program used, so read them with GetUiInstructionParameters before writing one. The answer is written first, then the parameter marking the dialogue as completed. Writing a parameter needs the Rapid mastership, and fails when the instruction is no longer pending.

Methods of RapidService :
// Gets the dialogue a running RAPID program is currently asking an operator for (synchronous) Answering it means writing its parameters with String%2cSystem.String), addressed by the path this returns.
RapidUiInstruction GetActiveUiInstruction();
// Gets the value of one parameter of a pending UI instruction (synchronous)
string GetUiInstructionParameter(string stackUrl, string parameter);
// Gets every parameter of a pending UI instruction: what the program passed in, and what it is waiting for (synchronous)
RapidUiInstructionParameter[] GetUiInstructionParameters(string stackUrl);
// Answers a pending UI instruction by writing one of its parameters (synchronous) An instruction is normally answered by writing the parameter carrying the answer and then the one marking it as completed.
void SetUiInstructionParameter(string stackUrl, string parameter, string value);

Every method also exists in an asynchronous version, with the same name followed by Async and an optional CancellationToken.

Members of Rws.Data.RapidUiInstruction :
public class RapidUiInstruction {
// Initializes a new instance of the <xref href="UnderAutomation.ABB.Rws.Data.RapidUiInstruction" data-throw-if-not-resolved="false"></xref> class
public RapidUiInstruction()
// What the instruction is asking of the client
public RapidUiInstructionEvent Event { get; set; }
// Level at which the instruction is executing
public RapidExecutionLevel ExecutionLevel { get; set; }
// Name of the RAPID instruction that opened the dialogue, for example "TPReadNum"
public string Instruction { get; set; }
// Text the instruction displays
public string Message { get; set; }
// Path identifying the call, which the parameter methods take
public string StackUrl { get; set; }
// Returns a string representation of this instruction
public override string ToString()
}
Members of Rws.Data.RapidUiInstructionParameter :
public class RapidUiInstructionParameter {
// Initializes a new instance of the <xref href="UnderAutomation.ABB.Rws.Data.RapidUiInstructionParameter" data-throw-if-not-resolved="false"></xref> class
public RapidUiInstructionParameter()
// Name of the parameter, for example "TPCompleted"
public string Name { get; set; }
// Returns a string representation of this parameter
public override string ToString()
// Value of the parameter, written the way RAPID writes it
public string Value { get; set; }
}
Members of Rws.Data.RapidUiInstructionEvent :
public enum RapidUiInstructionEvent {
// The instruction has been abandoned and no answer is expected any more
Abort = 3
// The instruction only displays something and expects no answer
Post = 2
// The instruction is waiting for an answer
Send = 1
// The controller reported an event this library does not know
Unknown = 0
}

Signals renamed by the program

A RAPID program can give another name to an I/O signal. GetAliasIo lists these names as long as the program declaring them is loaded. The signals themselves are read and written with the I/O service.

// The signals a loaded program gave another name to. Empty when no program declares any.
foreach (RapidAliasIoItem alias in robot.Rws.Rapid.GetAliasIo())
{
Console.WriteLine(alias.AliasName + " -> " + alias.SignalName + " (" + alias.Type + ")");
}
Methods of RapidService :
// Gets the I/O signals a running RAPID program has given an alias to (synchronous)
RapidAliasIoItem[] GetAliasIo(int? start = null, int? limit = null);

Every method also exists in an asynchronous version, with the same name followed by Async and an optional CancellationToken.

Members of Rws.Data.RapidAliasIoItem :
public class RapidAliasIoItem {
// Initializes a new instance of the <xref href="UnderAutomation.ABB.Rws.Data.RapidAliasIoItem" data-throw-if-not-resolved="false"></xref> class
public RapidAliasIoItem()
// Name the RAPID program refers to the signal by
public string AliasName { get; set; }
// Name of the I/O signal the alias points at
public string SignalName { get; set; }
// Returns a string representation of this alias
public override string ToString()
// Type of the aliased signal
public IoSignalType Type { get; set; }
}

Position of the robot

The position of the robot, its mechanical units and the external axes of a task are read from the motion system service.

View as Markdown

Universal Robots, Fanuc, Yaskawa, ABB 또는 Staubli 로봇을 .NET, Python, LabVIEW 또는 Matlab 애플리케이션에 쉽게 통합

UnderAutomation
문의하기Legal

© All rights reserved.