Implementation:CARLA simulator Carla MultiGPU Secondary
| Knowledge Sources | |
|---|---|
| Domains | MultiGPU, Networking |
| Last Updated | 2026-02-15 05:00 GMT |
Overview
Secondary is a TCP client that connects to the primary CARLA server, receives commands and frame data, processes them through a SecondaryCommands handler, and sends responses back.
Description
The Secondary class in carla::multigpu represents the client side of a multi-GPU connection. A secondary GPU rendering process creates a Secondary instance to connect back to the primary server's Router. It inherits from std::enable_shared_from_this<Secondary>, profiler::LifetimeProfiled, and NonCopyable.
Construction:
Two constructors are provided: one accepting a boost::asio::ip::tcp::endpoint and one accepting an IP string plus port number. Both take a SecondaryCommands::callback_type that defines how to handle incoming commands. The constructor initializes a ThreadPool, TCP socket, strand, connection timer, and BufferPool.
Connection lifecycle:
- Connect(): Starts 2 async worker threads, posts an async connection attempt to the strand. On success, disables Nagle's algorithm (TCP_NODELAY) and begins ReadData(). On failure, calls Reconnect().
- Reconnect(): Schedules a retry after 1 second using a deadline_timer.
- Stop(): Cancels the connection timer and closes the socket with a _done atomic flag to prevent further operations.
Write methods:
- Write(shared_ptr<const tcp::Message>): Sends a pre-built TCP message via async_write with strand serialization.
- Write(Buffer): Wraps a Buffer in a BufferView, builds a tcp::Message, and sends it.
- Write(std::string): Sends a size-prefixed string in two async writes (size integer first, then character data).
ReadData():
Implements the same two-phase read protocol as Primary: reads the message size header first, then reads the full payload. On success, passes the buffer to SecondaryCommands::process_command() which decodes the CommandHeader and dispatches the appropriate handler. Then recursively calls ReadData for continuous reception.
MakeMessage(): Static factory that accepts SharedBufferView arguments and constructs a tcp::Message shared pointer.
Usage
A secondary GPU server process creates a Secondary instance, connects to the primary server, and processes commands (frame data, map loads, token requests, ROS control) received from the primary through the SecondaryCommands callback system.
Code Reference
Source Location
- Repository: CARLA
- Files:
LibCarla/source/carla/multigpu/secondary.hLibCarla/source/carla/multigpu/secondary.cpp
Signature
class Secondary
: public std::enable_shared_from_this<Secondary>,
private profiler::LifetimeProfiled,
private NonCopyable {
public:
using endpoint = boost::asio::ip::tcp::endpoint;
using protocol_type = endpoint::protocol_type;
Secondary(boost::asio::ip::tcp::endpoint ep, SecondaryCommands::callback_type callback);
Secondary(std::string ip, uint16_t port, SecondaryCommands::callback_type callback);
~Secondary();
void Connect();
void Stop();
void AsyncRun(size_t worker_threads);
void Write(std::shared_ptr<const tcp::Message> message);
void Write(Buffer buffer);
void Write(std::string text);
SecondaryCommands &GetCommander();
template <typename... Buffers>
static auto MakeMessage(Buffers... buffers);
};
Import
#include "carla/multigpu/secondary.h"
I/O Contract
Inputs
| Name | Type | Required | Description |
|---|---|---|---|
| ep | boost::asio::ip::tcp::endpoint | Yes (ctor 1) | TCP endpoint of the primary server to connect to |
| ip | std::string | Yes (ctor 2) | IP address of the primary server |
| port | uint16_t | Yes (ctor 2) | TCP port of the primary server |
| callback | SecondaryCommands::callback_type | Yes | Command processing callback for incoming primary commands |
| message | shared_ptr<const tcp::Message> | Yes (Write) | Pre-built TCP message to send |
| buffer | Buffer | Yes (Write) | Raw buffer to wrap and send |
| text | std::string | Yes (Write) | Size-prefixed text to send |
Outputs
| Name | Type | Description |
|---|---|---|
| GetCommander() | SecondaryCommands& | Reference to the command processor for registering handlers |
| MakeMessage() | shared_ptr<const tcp::Message> | Constructs a TCP message from BufferView arguments |
| (callback invocations) | void | Incoming commands dispatched through SecondaryCommands |
Usage Examples
// Create a secondary that connects to the primary server
auto secondary = std::make_shared<carla::multigpu::Secondary>(
"192.168.1.1", 2002,
[](carla::multigpu::MultiGPUCommand cmd, carla::Buffer data) {
// Handle commands from primary: frame data, map loads, etc.
switch (cmd) {
case MultiGPUCommand::SEND_FRAME:
// Process frame data
break;
case MultiGPUCommand::LOAD_MAP:
// Load the specified map
break;
}
});
// Connect to the primary server (auto-reconnects on failure)
secondary->Connect();
// Send a response back to the primary
secondary->Write(std::move(responseBuffer));
// Shutdown
secondary->Stop();