The Interpreter Mode of a Universal Robots cobot runs URScript statements sent by your application while a robot program is running. Unlike the URScript of the Primary Interface, it does not stop the program: the statements run in the program, and the program continues after them. This page shows how to send statements and follow their execution.

## How it works

1. The robot program calls the URScript function `interpreter_mode()`. The program waits there.
2. The SDK sends statements. The robot adds them to a buffer and runs them in order.
3. The SDK ends the interpreter mode: the robot program continues after `interpreter_mode()`.

![Interpreter mode in PolyScope](/universal-robots/interpreter-mode-polyscope.jpg)

See [Interpreter mode](https://www.universal-robots.com/articles/ur/programming/interpreter-mode/) by Universal Robots, and the PolyScope versions that support it.

## Prerequisites

- The service `Interpreter Mode Socket` is enabled on the robot: see [Prepare the robot](/universal-robots/documentation/connect#prepare_the_robot).
- A program that calls `interpreter_mode()` is running.

## Example

Interpreter Mode is disabled by default: set `InterpreterMode.Enable` in `ConnectParameters`.

**C# : InterpreterMode**
```csharp
using UnderAutomation.UniversalRobots;
using UnderAutomation.UniversalRobots.InterpreterMode;

class InterpreterMode
{
  static void Main(string[] args)
  {
    /**/
    var robot = new UR();

    var parameters = new ConnectParameters("192.168.0.1");

    // Interpreter Mode is disabled by default
    parameters.InterpreterMode.Enable = true;

    robot.Connect(parameters);

    // The robot program must be in interpreter_mode()
    CommandResponse response = robot.InterpreterMode.ExecuteCommand("movej([0.94, -1.31, 2.21, -2.65, -1.08, 4.81], a=1, v=0.5)");

    if (response.Status != CommandResponseStatus.Ack)
      Console.WriteLine(response.RawAnswer);

    robot.InterpreterMode.ExecuteCommand("set_standard_digital_out(1, True)");

    // Id of the last statement executed by the robot
    CommandResponse lastExecuted = robot.InterpreterMode.StateLastExecuted();

    // Remove the statements not executed yet
    robot.InterpreterMode.SkipBuffer();

    // Leave interpreter_mode(): the robot program continues
    robot.InterpreterMode.EndInterpreter();

    // Close Interpreter Mode only
    robot.InterpreterMode.Disconnect();
    /**/
  }
}
```

**Python : InterpreterMode**
```python
from underautomation.universal_robots.ur import UR
from underautomation.universal_robots.connect_parameters import ConnectParameters
from underautomation.universal_robots.interpreter_mode.command_response_status import CommandResponseStatus

##
robot = UR()

parameters = ConnectParameters("192.168.0.1")

# Interpreter Mode is disabled by default
parameters.interpreter_mode.enable = True

robot.connect(parameters)

# The robot program must be in interpreter_mode()
response = robot.interpreter_mode.execute_command("movej([0.94, -1.31, 2.21, -2.65, -1.08, 4.81], a=1, v=0.5)")

if response.status != CommandResponseStatus.Ack:
    print(response.raw_answer)

robot.interpreter_mode.execute_command("set_standard_digital_out(1, True)")

# Id of the last statement executed by the robot
last_executed = robot.interpreter_mode.state_last_executed()

# Remove the statements not executed yet
robot.interpreter_mode.skip_buffer()

# Leave interpreter_mode(): the robot program continues
robot.interpreter_mode.end_interpreter()

# Close Interpreter Mode only
robot.interpreter_mode.disconnect()
##
```

## Commands

| Method                    | Role                                                                    |
| ------------------------- | ----------------------------------------------------------------------- |
| `ExecuteCommand(script)`  | Add a statement to the buffer. `Ack` when the robot accepts it, `Discard` when it does not compile or no program runs |
| `StateLastExecuted()`     | Largest id of a statement that has started                              |
| `StateLastInterpreted()`  | Largest id of a statement interpreted                                   |
| `StateLastCleared()`      | Id of the last statement cleared, by the end or by `ClearInterpreter()` |
| `StateLastUnexecuted()`   | Number of statements not executed yet                                   |
| `SkipBuffer()`            | Skip the statements not executed yet, after the one that runs           |
| `ClearInterpreter()`      | Clear the statements, functions and threads interpreted so far          |
| `Abort()`                 | Stop the `movej` or `movel` that runs, with a controlled stop           |
| `EndInterpreter()`        | Leave `interpreter_mode()`: the robot program continues                 |

Each method returns a `CommandResponse`: its `Status`, its `Id` and the raw answer of the robot.

The buffer of the robot has a limited size. For a long sequence, follow `StateLastExecuted()` and call `ClearInterpreter()` from time to time.

## Try it in the demo application

Everything on this page can be tried without writing code, in the **Interpreter mode** page of the [demo application](/universal-robots/documentation/demo-app).

![Interpreter mode page of the Universal Robots SDK demo application](/universal-robots/WinformsScreenshots/InterpreterMode.jpg)

Its C# source is [InterpreterModeControl.cs](https://github.com/underautomation/UniversalRobots.NET/blob/main/UnderAutomation.UniversalRobots.Showcase.Forms/Components/InterpreterModeControl.cs).

## Reference

**Members of InterpreterMode.Internal.InterpreterModeClientBase**
```csharp
public abstract class InterpreterModeClientBase : URServiceBase {
    protected InterpreterModeClientBase()

    // The interpreter mode offers a mechanism to abort limited number of script functions, even if they are
    // called from the main program. Currently only movej and movel can be aborted.
    // Aborting a movement will result in a controlled stop if no blend radius is defined.
    // If a blend radius is defined then a blend with the next movement will be initiated right away if not
    // already in an initial blend, otherwise the command is ignored.
    // Return value should be ignored
    public CommandResponse Abort()

    // Clears all interpreted statements, objects, functions, threads, etc. generated in the current
    // interpreter mode.Threads started in current interpreter session will be stopped, and deleted.
    // Variables defined outside of the current interpreter mode will not be affected by a call to thisfunction.
    // Only statements interpreted before the clear_interpreter() function will be cleared.
    // Statements sent after clear_interpreter() will be queued. When cleaning is done, any
    // statements queued are interpreted and responded to. Note that commands such as abort,
    // skipbuffer and state commands are executed as soon as they are received.
    public CommandResponse ClearInterpreter()

    // Connects to the interpreter mode server at the specified IP and port.
    protected void ConnectInternal(string ip, int port)

    // Indicates that the interpreter mode client is connected and ready to send commands
    public bool Connected { get; }

    // Disconnect interpreter mode socket connection
    public void Disconnect()

    // Ends the interpreter mode, and causes the interpreter_mode() function to return. This
    // function can be compiled into the program by sending it to the interpreter socket(30020) as any
    // other statement, or can be called from anywhere else in the program.
    // By default everything interpreted will be cleared when ending, though the state of the robot, the
    // modifications to local variables from the enclosing scope, and the global variables will remain
    // affected by any changes made.The interpreter thread will be idle after this call.
    public CommandResponse EndInterpreter()

    // Executes a command on the Interpreter Mode
    public CommandResponse ExecuteCommand(string command)

    // IP of the robot to connect to for sending commands
    public string IP { get; }

    // Interpreter mode server port
    public int Port { get; set; }

    // The interpreter mode furthermore supports the opportunity to skip already sent but not executed
    // statements.The interpreter thread will then(after finishing the currently executing statement) skip
    // all received but not executed statements.
    // After the skip, the interpreter thread will idle until new statements are received.skipbuffer will
    // only skip already received statements, new statements can therefore be send right away.
    // Return value should be ignored
    public CommandResponse SkipBuffer()

    // Replies with the id for the latest statement to be cleared from the interpreter mode. This clear can happen when ending interpreter mode, or by calls to clear_interpreter()
    public CommandResponse StateLastCleared()

    // Replies with the largest id of a statement that has started being executed.
    public CommandResponse StateLastExecuted()

    // Replies with the latest interpreted id, i.e. the highest number of interpreted statement so far.
    public CommandResponse StateLastInterpreted()

    // Replies with the number of non executed statements, i.e. the number of statements that would have be skipped if skipbuffer was called instead.
    public CommandResponse StateLastUnexecuted()
}
```

**Members of InterpreterMode.CommandResponse**
```csharp
public class CommandResponse {
    // Answer from the interpreter mode
    public string Body { get; }

    // Command sent to the interpreter mode
    public string Command { get; }

    public override bool Equals(object obj)

    public override int GetHashCode()

    // Command unique identifier
    public int Id { get; }

    // Raw line sent from the controller
    public string RawAnswer { get; }

    // Response type to check if command succeed
    public CommandResponseStatus Status { get; }

    public override string ToString()
}
```

**Members of InterpreterMode.CommandResponseStatus**
```csharp
public enum CommandResponseStatus {
    // The command compilation succeed and Interpreter mode will execute the statement
    Ack = 0

    // Program is not running or the statement results in a compilation or linker error
    Discard = 1

    // Something went wrong when receiving response
    Error = -1

    // Answer from a state command
    State = 2
}
```

**Members of Common.InterpreterModeConnectParameters**
```csharp
public class InterpreterModeConnectParameters : InterpreterModeClientParametersBase {
    // Enable Interpreter Mode client communication
    // Default value is false
    public bool Enable { get; set; }
}
```

## What to read next

- [Send URScript](/universal-robots/documentation/remote-send-script): run URScript without a running program.
- [Move the robot from a PC](/universal-robots/documentation/how-to-move-robot): which way to choose for a move.