Main Content

Control RoadRunner Programmatically Using gRPC API

RoadRunner provides an API that enables you to control the RoadRunner UI programmatically. For example, using this API, you can:

  • Create, load, and save RoadRunner scenes, scenarios, and projects.

  • Import ASAM OpenDRIVE® files into scenes.

  • Export scenes and scenarios to one of the file formats that RoadRunner supports.

RoadRunner enables you to compile versions of the API in various programming languages and call them in the language you choose. Alternatively, you can use a precompiled version of the API that enables you to control RoadRunner from the command line.

How the RoadRunner API Works

The RoadRunner API is built using the open-source gRPC® framework. This framework uses a client-server architecture in which a client application remotely controls a server application using a set of remote procedure call (RPC) methods. In RoadRunner:

  • Your locally installed version of RoadRunner is the server application.

  • The RoadRunner API provides the RPC methods used to remotely control RoadRunner.

  • The programs you write to call the RPC methods are the client applications. The gRPC framework is language-neutral and platform-neutral. You can write clients that call the RoadRunner API in any platform and language that gRPC supports. For details on what languages and platforms gRPC supports, see the gRPC Documentation.

This diagram shows a simplified layout of the API architecture. In this diagram, a Python® client uses the LoadScene method to load a scene in RoadRunner.

A Python client, myClient.py, calls the LoadScene RPC method to load a scene on the RoadRunner server.

How the RoadRunner API Sends and Receives Data

The RPC methods of the RoadRunner API are defined in a gRPC service. Each time you call a method that is part of a gRPC service, that method:

  • Sends a request to a server.

  • Receives a response back from the server.

This diagram shows this request-response format for a call of the LoadScene method. In the client, the input to the method, LoadSceneRequest, is a request that the client sends the RoadRunner application server. RoadRunner processes this request, loads a scene, and sends back a response, LoadSceneResponse.

The RoadRunner request-response relationship

The data in these requests and responses is structured as messages that are defined using the protocol buffer (protobuf) schema. The protobuf schema is a language-neutral format developed by Google®, and is optimized for fast and efficient data transfer. The RoadRunner server can send and receive millions of protobuf messages from these API calls simultaneously while maintaining real-time updates of RoadRunner.

Messages in the protobuf schema are defined in text files with a .proto extension. These messages contain name-value fields that define:

  • The names of the fields that you can specify in the messages.

  • The data types of the fields. For example, you can specify fields as Boolean values, strings, or as other protobuf messages.

Consider the schema for the LoadScene RPC method, as defined in the roadrunner_service.proto file.

// Load scene 
rpc LoadScene (LoadSceneRequest) returns (LoadSceneResponse) {}

The schema for the request message, LoadSceneRequest, and response message, LoadSceneResponse, are defined in the roadrunner_service_messages.proto file. LoadSceneRequest takes in one required input, file_path, which is a string that specifies the path of the file to load.

message LoadSceneRequest
{
  // Scene file to load (required)
  string file_path = 1;
}

After RoadRunner processes the request (tries to load the scene), the RoadRunner API server sends back an empty LoadSceneResponse message in response.

message LoadSceneResponse
{
}

Since the protobuf schema is language-neutral, the syntax used to call the methods and format your message requests depends on the programming language you use to write your client applications.

Connect to RoadRunner API Server

To use the RoadRunner API, you must first establish a network connection with the RoadRunner API server. This server is a part of your local RoadRunner installation and starts running when you open a project.

To programmatically open RoadRunner and start the API server, call the AppRoadRunner executable from your local RoadRunner installation. This executable contains command-line options that enable you to specify:

  • The project that RoadRunner opens to

  • The IP network port that the RoadRunner API server runs on

This command-line code shows how to open RoadRunner from its default installation location on Windows®. RoadRunner opens to a project located at C:\RR\MyProject on IP network port 54321.

cd "C:\Program Files\RoadRunner R2025a\bin\win64"
AppRoadRunner --projectPath C:\RR\MyProject --apiPort 54321

The Output pane of RoadRunner displays the port on which RoadRunner API server is running.

Output pane with RoadRunner API server message

Use RoadRunner API from Command Line

RoadRunner provides a precompiled helper command, CmdRoadRunnerApi, that enables you to call RoadRunner RPC methods from the command line. This helper command is located in the same folder as the AppRoadRunner executable.

This code calls the LoadScene method to load the prebuilt FourWaySignal scene from the open project.

CmdRoadRunnerApi "LoadScene(file_path='FourWaySignal')" --serverAddress=localhost:54321

RoadRunner scene containing a four-way intersection with traffic signals

Use RoadRunner API in Various Programming Languages

For additional flexibility in using the RoadRunner API, you can compile the API into a language supported by gRPC, and then write client applications in that language to control RoadRunner programmatically.

Compile RoadRunner API

To compile the RoadRunner API in your desired programming language, you must first copy the protobuf files that define the API into a writable folder. These files are located in your local RoadRunner installation. You can then use the protobuf compiler, along with the gRPC plugin for your desired programming language, to compile language-specific versions, or bindings, of the RoadRunner API. For example, this diagram shows the generation of Python and C++ bindings.

Protobuf files compiled into Python and C++ bindings using the protobuf compiler and gRPC plugins.

For details on compiling the protobuf files, see Compile Protocol Buffers for RoadRunner gRPC API.

Create RoadRunner API Clients

The clients that you write to programmatically control RoadRunner typically contain code that performs these steps:

  1. Import gRPC code from the compiled bindings.

  2. Establish a local network connection to the RoadRunner API server.

  3. Use the imported gRPC code to create a RoadRunner API object. This object is called a stub.

  4. Call the RPC methods from this stub to control RoadRunner over the local network.

This simple Python client shows an example of calling the LoadScene method.

import grpc
from mathworks.roadrunner import roadrunner_service_messages_pb2
from mathworks.roadrunner import roadrunner_service_pb2_grpc

with grpc.insecure_channel("localhost:54321") as channel:
    api = roadrunner_service_pb2_grpc.RoadRunnerServiceStub(channel)
    loadSceneRequest = roadrunner_service_messages_pb2.LoadSceneRequest()
    loadSceneRequest.file_path = "FourWaySignal"
    api.LoadScene(loadSceneRequest)

After importing the compiled gRPC Python bindings, this client establishes a connection over a gRPC channel and creates a stub for the RoadRunner service API. The gRPC channel for the API uses insecure channel credentials and has no encryption or authentication. Since RoadRunner typically runs on a local machine and is not connecting to external networks, the security risk is low. Then, the client calls LoadScene from the API stub, which loads the prebuilt FourWaySignal scene from the currently open project.

You can have multiple clients calling RPC methods simultaneously, as long they are connected to RoadRunner on the same network port. For example, in this diagram, both a Python client and C++ client are calling LoadScene over network port 54321.

A Python client, myClient.py, and C++ client, myClient.cc, calling LoadScene over port 54321.

See Also

Topics