Apollo CyberRT

repository·v10.0.0·Indexed 43 days ago

https://github.com/minhanghuang/cyberrt

A high-performance, real-time middleware framework designed for autonomous driving systems. It provides communication primitives including channels, nodes, and services, along with tools for monitoring and recording data. Supports C++ integration via CMake and a Python API for developing application modules.

Tokens
33.8K
Snippets
99
Records
145
Agent score
54%

What's inside CyberRT

  1. Overview of Apollo Cyber RT

    v10.0.0

    Apollo Cyber RT is an open-source, high-performance runtime framework specifically designed for autonomous driving scenarios. It is based on a centralized computing model and is optimized for high concurrency, low latency, and high throughput.

    Key advantages include:

    • Accelerated Development: Provides clearly defined task interfaces, data fusion, a suite of development tools, and numerous sensor drivers.
    • Simplified Deployment: Features efficient adaptive information communication, resource-aware configurable user-level schedulers, and high portability with fewer dependencies.
    • Autonomous Driving Empowerment: Serves as a default open-source runtime framework with components designed specifically for AD (Autonomous Driving) systems, allowing for plug-and-play integration of custom systems.
  2. Overview of common-msgs package

    v10.0.0
    The common-msgs package provides the standardized message definitions required for data transmission across various channels in the CyberRT framework. It acts as a central repository for all message types used by different modules, ensuring consistent data structures for communication between components like perception, planning, and control.
  3. Overview of Topological Communication APIs in C++

    v10.0.0

    Topological communication in CyberRT is implemented through three primary abstraction layers:

    1. node: The fundamental unit of execution and management.
    2. reader/writer: Used for data publication and subscription (Pub/Sub) patterns.
    3. client/service: Used for request/response patterns.

    To use these APIs, you should navigate to the specific documentation for node, reader/writer, or client/service to understand their respective method signatures and lifecycles.

  4. Understand the Talker-Listener pattern in CyberRT

    v10.0.0

    CyberRT communication is built on three fundamental concepts:

    1. Node: The basic unit of the framework (similar to a handle). All functional objects like readers and writers must be created from a node instance.
    2. Writer: A facility used to send messages to a specific channel.
    3. Reader: A facility used to receive messages from a channel. It must be bound to a callback function that is triggered whenever a new message arrives.

    Before using these, you must initialize the framework using apollo::cyber::Init().

    // Basic lifecycle
    apollo::cyber::Init(argv[0]);
    auto node = apollo::cyber::CreateNode("my_node");
    // ... use node to create readers/writers ...
    apollo::cyber::WaitForShutdown();
  5. Migrate folder structure from ROS to Cyber RT

    v10.0.0

    Cyber RT simplifies the project structure by removing the src folder. Source files are placed in the same directory as the BUILD file.

    ROS Structure:

    • CMakeLists.txt
    • package.xml
    • proto/ (contains .proto files)
    • src/ (contains .cpp files)

    Cyber RT Structure:

    • BUILD (replaces CMakeLists.txt and package.xml)
    • *.cc (source files in the root)
    • proto/ (contains .proto files AND a BUILD file for the proto library)
  6. Build modules using the Component base class

    v10.0.0

    Cyber RT provides two ways to build applications:

    1. Binary based: The application is a standalone binary that creates its own Reader and Writer to communicate.
    2. Component based: The application is compiled into a Shared Library (.so). The framework dynamically loads it using a DAG (Directed Acyclic Graph) configuration file.

    Component Advantages:

    • Flexible deployment via launch files.
    • Change received channel names in the DAG file without recompiling.
    • Supports multiple data types and fusion strategies.

    Essential Interface:

    • Init(): Performs algorithm initialization (similar to main).
    • Proc(): A callback function triggered by the framework when a message arrives (similar to a Reader callback).
    class MyComponent : public Component<MessageType, MessageType> {
     public:
      bool Init() override;
      bool Proc(const std::shared_ptr<MessageType>& msg) override;
    };
    CYBER_REGISTER_COMPONENT(MyComponent)
  7. Explore common-msgs directory structure

    v10.0.0

    The common-msgs package is organized into subdirectories by functional domain. Each subdirectory contains the specific message definitions for that module. Key message groups include:

    • Core/Basic: basic_msgs, transform_msgs
    • Vehicle Control & Chassis: chassis_msgs, control_msgs, drivers_msgs
    • Sensing & Perception: perception_msgs, prediction_msgs, sensor_msgs, localization_msgs
    • Planning & Navigation: planning_msgs, routing_msgs, map_msgs
    • System & Monitoring: config_msgs, monitor_msgs, task_manager_msgs
    • External/Specialized: v2x_msgs, audio_msgs, simulation_msgs, dreamview_msgs
    modules/common_msgs/
    ├── audio_msgs              // Message definitions of audio
    ├── basic_msgs              // Common message definitions
    ├── BUILD
    ├── chassis_msgs            // Message definitions of chassis 
    ├── config_msgs             // Message definitions of config in multiple modules
    ├── control_msgs            // Message definitions of control 
    ├── cyberfile.xml
    ├── dreamview_msgs          // Message definitions of dreamview
    ├── drivers_msgs            // Message definitions of drivers component
    ├── external_command_msgs   // Message definitions of external_command   
    ├── guardian_msgs           // Message definitions of guardian_msgs 
    ├── localization_msgs       // Message definitions of localization
    ├── map_msgs                // Message definitions of map
    ├── monitor_msgs            // Message definitions of monitor
    ├── perception_msgs         // Message definitions of perception
    ├── planning_msgs           // Message definitions of planning
    ├── prediction_msgs         // Message definitions of prediction
    ├── README.md
    ├── routing_msgs            // Message definitions of routing
    ├── sensor_msgs             // Message definitions of multiple sensors
    ├── simulation_msgs         // Message definitions for simulation
    ├── storytelling_msgs       // Message definitions of storytelling
    ├── task_manager_msgs       // Message definitions of task-manager
    ├── transform_msgs          // Message definitions of transform
    └── v2x_msgs                // Message definitions of v2x
  8. Manage parameters with ParameterService and ParameterClient

    v10.0.0

    CyberRT uses a parameter system to allow nodes to share configuration.

    ParameterService: Used by a node to host and manage parameters.

    • SetParameter(const Parameter& parameter): Sets a parameter.
    • GetParameter(const std::string& param_name, Parameter* parameter): Retrieves a parameter.
    • ListParameters(std::vector<Parameter>* parameters): Lists all available parameters.

    ParameterClient: Used by other nodes to access parameters hosted by a service node.

    • SetParameter(const Parameter& parameter): Updates a parameter on the remote service.
    • GetParameter(const std::string& param_name, Parameter* parameter): Fetches a parameter from the remote service.
    • ListParameters(std::vector<Parameter>* parameters): Lists parameters from the remote service.

    Parameter Object: Parameters can be initialized with various types including bool, int, int64_t, float, double, std::string, or even complex google::protobuf::Message objects.

  9. Communication Patterns in Cyber RT

    v10.0.0

    Cyber RT supports multiple communication patterns for data transfer between nodes:

    1. Data Streaming (Pub/Sub)

    • Channel: The mechanism used to manage data communication. Users publish to or subscribe to a channel to achieve peer-to-peer (p2p) communication.
    • Reader/Writer: The primary message transfer interfaces. These are typically created within a Node to read from or write to a Channel.

    2. Request/Response (Service/Client)

    • Service/Client: A pattern supporting two-way communication. A Client node makes a request to a Service node and receives a response.
    • Parameter Service: A specialized service/client pattern that provides a global interface for accessing parameters across Cyber RT.

    3. Service Discovery

    Cyber RT uses a decentralized design. There is no central master node for registration; instead, nodes use Service Discovery (implemented via UDP) to find other service nodes.

  10. How the Talker-Listener model works in CyberRT

    v10.0.0

    CyberRT communication is based on the Talker-Listener pattern using three core abstractions:

    1. Node: The fundamental unit of the framework (similar to a handle). All functional objects like writers and readers must be created from a node instance.
    2. Writer: A facility used to send messages to a specific channel. Each writer is tied to a specific data type.
    3. Reader: A facility used to receive messages from a channel. A reader must be bound to a callback function that is triggered whenever a new message arrives on that channel.

    To use these, you must first initialize the framework using apollo::cyber::Init().

    // 1. Initialize
    apollo::cyber::Init(argv[0]);
    
    // 2. Create Node
    auto node = apollo::cyber::CreateNode("my_node");
    
    // 3. Create Writer (Talker)
    auto writer = node->CreateWriter<MessageType>("channel_name");
    
    // 4. Create Reader (Listener)
    auto reader = node->CreateReader<MessageType>("channel_name", [](const std::shared_ptr<MessageType>& msg) {
        // Handle message
    });
  11. Core Abstractions in Cyber RT

    v10.0.0

    Cyber RT is built around several key abstractions that define how modules interact and execute tasks:

    • Node: The fundamental building block. Every module uses nodes to facilitate communication.
    • Component: A high-level module (e.g., perception, localization) that exists as a collection of components. Components are decoupled and communicate via Channels.
    • Task: An abstract description of an asynchronous computation task.
    • CRoutine: A coroutine implementation used to optimize thread usage and system resource allocation.
    • Scheduler: Provides various resource scheduling algorithms tailored for autonomous driving scenarios.
    • Message: The basic unit of data transferred between modules.