494. fRPC Example
The communication between Foretify and SSP/DSP is done by transmitting Protobuf messages using Foretellix fRPC library.
The following sections contain examples of implementing an SSP in C++ and Python. The examples show only the SSP implementation; however, the same flow is used when implementing a DSP.
For now, the SSP and DSP can be implemented in C++ and Python. Both are supported by Protobuf and fRPC. Support in other languages can be available if needed.
To implement the RPCs for the SSP and DSP, the developer needs to implement a set of functions, one for each RPC type as defined in the SSP/DSP APIs.
494.1 SSP C++ Code example
The user class "SSPService" contains the implementation of methods that are called on each RPC invoked by Foretify. It should implement any of the methods defined in the auto-generated class "fRPC::ssp::Service".
#include <frpc.hpp>
#include <frpc_ssp.h>
class SSPService final: public fRPC::ssp::Service {
public:
bool init(
const ::foretify_ssp::init_req& request,
::foretify_ssp::init_resp& response) override
{
// Implementation of "init" RPC
// Example of reading input variables
auto step_size = request.info().step_size_ms();
// Example of writing output variables
response.mutable_status()->add_error("Failed to start SSP");
return true;
}
bool launch_simulator(
const ::foretify_ssp::launch_simulator_req& request,
::foretify_ssp::launch_simulator_resp& response) override
{
// Implementation of "launch_simulator" RPC
return true;
}
// ... rest of the methods as defined in the SSP API
};
The "main" method below represents the entry point for the SSP component. When the SSP is implemented as a shared object, the code below should be inserted into an initialization function provided by the simulator.
int main()
{
// Declares an instance of the user service class as defined above
SSPService service;
// Generate a fRPC server listening on a "<server_address>" as configured
frpc_server* frpc = new Server<Empty::Stub>(&service);
// Blocks until a connection from Foretify received
frpc->start_listen(<server_address>); // Supported formats: tcp:<host>:<port> or unix:<path>
frpc->wait_for_connection(<timeout_ms>);
// Sample messages from Foretify until receiving an "end_simulation" messages
while (!sim_end)
{
try
{
// Blocking until request is received
// Calls the appropriate callback in SSPService directly
frpc->handle_request();
}
catch (frpc_connection_error& e)
{
throw std::runtime_error(e.what());
}
catch (frpc_runtime_error& e)
{
throw std::runtime_error(e.what());
}
}
return 0;
}
494.2 SSP Python Code example
The user class "SSPService" contains the implementation of methods that are called on each RPC invoked by Foretify. It should implement any of the methods defined in the auto-generated class "frpc_SSP_service".
import frpc
from frpc_ssp import frpc_ssp_service as frpc_SSP_service
class SSPService(frpc_SSP_service):
def init(self, request, response):
# Implementation of "init" RPC
# Example of reading input variables
step_size = request.info.step_size_ms
# Example of writing output variables
response.error.extend("Failed to start SSP");
return True
# ... rest of the methods as defined in the SSP API
This code represents the entry point for the SSP component.
if __name__ == '__main__':
# Generate a fRPC server listening on a "<server_address>" as configured
frpc = frpc.fRPC(SSPService())
frpc.start_listen(<server_address>) # Supported formats: tcp:<host>:<port> or unix:<path>
frpc.wait_for_connection(<timeout_ms>)
# Sample messages from Foretify until receiving an "end_simulation" messages
while True:
try:
# Blocking until request is received
# Calls the appropriate callback in SSPService directly
frpc.handle_request()
except frpc.frpc_connection_error:
break
except frpc.frpc_runtime_error:
break