5. Secondary Development Program Deployment

This section will provide a complete description of the secondary development tool chain structure and how it is used, as provided by the think-tank.

5.1 Development Tools and Installation

5.1.1 System Requirements

  • Operating system: Ubuntu 22.04 LTS or higher (recommended Ubuntu 22.04 LTS)
  • Other systems supported:
    • MacOS 11.0 (Big Sur) or higher
    • Windows 10/11 Professional or enterprise version (WSL2 to be enabled)
  • Hardware Configuration
    • CPU: 8 cores or more (recommended 16 cores)
    • Memory: at least 32GB RAM (recommended 64 GB or more)
    • Storage space: at least 100 GB available disk space (for Docker mirrors and containers)
    • Network: Stable Internet connection (for downloading mirrors and dependence)

5.1.2 Create the Container Development Environment

It is recommended that the installation and configuration of Docker and vscode be completed on the mainframe before running the installation script.

  1. Obtaining a compressed package of AimDK-A3-v3.3-Bootstrap at the AimDK Downloading Centre to unpressure the catalogue structure as follows:
    • devcontainer.json# Defines the configuration of the development packaging
    • Setup_aimde.sh# installation script for the development environment

1. Implementation of script installation and development environment installation

bash
./setup_aimde.sh

Hint: If this is the first time you configure Docker, the system may prompt you to restart the computer to apply the user group permission settings. Once restart is complete, the installation script can be rerun and installed.

  • When vscode is automatically opened, the notification at the lower right corner will appear and click Reopen in Container
  • Open a new Terminal in vscode, enter setup-init and follow the hint.
  • See that Setup accessful represents setup successfully and can start developing and building the project

Copy DevKit package to mount directory

From the AimDK Download CenterGet the AimDK-A3-v3.3-DevKit compressor package and copy the DevKit package to the host mount directory~/sdk/a3/aimde/, the directory will automatically map into the container/workspaces/aimde/Path.

bash
# Execute on host
cp *sdk-package-a3-v3.3.13-0-gb889a630d-2610080917-devkit.tar.gz ~/sdk/a3/aimde/

5.1.3 Container Contents

/sdk directory

The SDK Root Directory, which includes the definition of the communication protocol, the Python package, the use of examples, and the development of the tool chain, the Bazel Building Rules and the pre-record library (x8664/aarch64) to support the compilation, development and deployment of the project.

python
/sdk
├── aima_protocol/                  # SDK communication protocol definitions (Protobuf / ROS 2 messages)
├── aima_protocol_py_pkg/           # Python package for SDK protocols
│   └── aimdk_proto-0.0.0+local-py3-none-any.whl   # Wheel that can be installed directly with pip
├── aimdk_examples/                 # SDK examples
└── dev_tools/                      # Development and build tools
    ├── x86_64/                     # Prebuilt SDK libraries (x86_64)
    ├── rk3588_aarch64/             # Prebuilt SDK libraries (RK3588/aarch64)
    ├── rule_ros2/                  # Bazel build rules for ROS 2
    ├── sdk-buildchain/             # Integrated build repository (unified build entry point)
    └── third_party_libs/           # Third-party dependencies

/opt/rockship directory

Provision of a cross-compiling tool chain for the RK 3588 platform and a partial tripartite repository.

bash
/opt/rockship
├── rk3588_sysroot  # Third-party libraries for ARM
└── rk3588-toolchain # Cross-compilation toolchain

/opt/nvidia

Provides the Nvidia Thor platform with a cross-compiling tool chain and a partial tripartite repository.

bash
/opt/rockship
├── thor_sysroot  # Third-party libraries for ARM
└── thor-toolchain # Cross-compilation toolchain

/workspaces/aimde directory

Develops the workspace, which contains the AimDK communications protocol, the example code, and the development packaging configuration.aima_protocolandaimdk_examplesBysetup-initYou can modify, compile and debug directly here from SDK.

bash
/workspaces/aimde
├── aima_protocol # SDK communication protocol definitions (Protobuf / ROS 2 messages)
├── aimdk_examples # SDK examples
└── .devcontainer # Dev Container configuration (image, mounts, environment variables, etc.)

5.2 Update Methods

To meet the needs of different stages of development, and taking into account the efficiency of renewal and environmental stability, SDK provides two flexible ways of updating. As SDK functions continue to overlap, bug fixes and optimizes performance, regular updates can help developers:

  • Get the latest API interface and functionality
  • Repair of known problems and enhancement of development experience and system stability
  • Consistency with official document and example code versions
  • Increased efficiency of compilation and operation as a result of optimized performance

Depending on the content of the update, the developer may choose an appropriate update strategy that ensures environmental integrity while improving the efficiency of the update:

Full Mirror Update

Scope of application:

  • Major Version Upgrade: Significant changes in core components such as SDK framework, development tool chain, system dependency, etc.
  • Environment completely reset: New development environment is needed to remove all historical configurations and caches
  • Cross-Video Update: upgrade directly from older version to latest version
  • System-level changes: updates of bottom components such as basic vessel mirrors, compilation tool chains, system libraries, etc.
  • First deployment: Initial installation of the development environment by new users

Features:

  • Ensuring environmental integrity and consistency
  • Recent version containing all dependencies and configurations
  • Long updating time (required to download and load full mirrors)
  • Once the container is rebuilt, unsustained data will be lost.

DevKit package update

Scope of application:

  • SDK Toolkit Reciprocal: update only SDK API, library files, development toolkit, etc.
  • Quick patch repair: Fix bugs in SDK or add minor features
  • Frequent Version Overlay: Development requires frequent testing of different DevKit versions
  • Keep Packaging Configuration: Need to maintain the existing packaging environment and personal configuration unchanged
  • Small version update: Update from v3.3-rc11 to small version changes such as v3.3-rc12

Features:

  • Update fast (replace only)/sdk/Contents)
  • Retain container configuration and user data
  • Fit for frequent overlaps and tests
  • Update SDK toolkit only, not the basic packaging environment
  • Reliance on change at the bottom may require a full mirror update

5.2.2 How to Choose an Update Method?

UpdateRecommended modalities
SDK Large Version Upgrade (e. g. v3.2 v3.3)Full Mirror Update
SDK small version upgrade (e.g. v3.3-rc11 v3.3-rc12)DevKit package update
Compile Tool Chain UpdatesFull Mirror Update
API Interface Change or AddDevKit package update
System Reliance Library UpgradeFull Mirror Update
Bug Repair PatchDevKit package update
There's been an anomaly in the container environment.Full Mirror Update

5.2.3 Full Image Update

  1. Update mirror version configuration

Edit.devcontainer/devcontainer.jsonDocumentation, willimageThe field is updated to a new mirror version number:tongyong-public-cn-shanghai.cr.volces.com/sdk/sdk-image-a3-v3.3.13-0-gb889a630d-2610080917:latest

  • Reconstruct the container

Execute command in VS Code:

  • PressF1orCtrl+Shift+POpen command panel
  • Enter and select:Dev Containers: Rebuild and Reopen in Container

5.2.4 DevKit Package Update

  1. Copy DevKit Package to Mount Directory

From the AimDK Download CenterGet the AimDK-A3-v3.3-DevKit compressor package and copy the DevKit package to the host mount directory~/sdk/a3/aimde/, the directory will automatically map into the container/workspaces/aimde/Path.

bash
# Execute on host
cp *sdk-package-a3-v3.3.13-0-gb889a630d-2610080917-devkit.tar.gz ~/sdk/a3/aimde/
  • Replace DevKit packages in containers

Enter the DevContainer terminal and perform the following command:

bash
# Clear Old Version
sudo rm -rf /sdk/*

# Unpress New Version to /sdk/ Directory
sudo tar -xvf /workspaces/aimde/*sdk-package-a3-v3.3.13-0-gb889a630d-2610080917-devkit.tar.gz -C /sdk/

# Cleaning of compressed packages (optional)
rm -rf /workspaces/aimde/*sdk-package-a3-v3.3.13-0-gb889a630d-2610080917-devkit.tar.gz

5.2.5 Update the Workspace Project

When the SDK version is updated, the protocol definition and the example code in the synchronised workspace are required. The following steps are recommended:

1. Delete old version of the table of contents

bash
rm -rf /workspaces/aimde/aima_protocol /workspaces/aimde/aimdk_examples

This operation removes all local changes under these two directories. If changes need to be kept, either backup or submit them to the version library.

2. Re-introduction of the workspace

bash
setup-init

setup-initI'll pull back the latest from SDK.aima_protocolandaimdk_examplesGo to the workspace.

5.2.6 Notes

  • Suggest backup of key data and configuration files before updating
  • Make sure Docker's service is running properly
  • The full mirror update will recreate the container and the data on non-sustainability in the container will be lost
  • DevKit update to replace only the SDK toolkit without affecting packaging configuration

5.3 Third-Party Library Management

The commonly used tripartite library on which the framework is built has been pre-integrated in the local development environment (aimde), managed centrally through Bazel rule, which allows users to be introduced as required in the business code without having to download and install them themselves. The framework also supports users to add the tripartite library as needed and to manage and quote in the same way.

5.3.1 Third-Party Library Definition Chain

The three-tier library, from local files to business code, is defined in three layers, with a single function:

plain
/sdk/dev_tools/third_party_libs/external/xxx        # Library files (source or prebuilt)
        │  1. sdk_third_party_deps.bzl: register local_repository as a Bazel external repository
        ▼
@xxx / @xxx_x86_64 / @xxx_aarch64                    # External repository
        │  2. integration/BUILD: use alias + select to hide architecture and source differences
        ▼
@integration//:xxx                                   # Unified SDK entry point
        │  3. aimdk_examples/thirdparty/BUILD: forward aliases to the local application repository
        ▼
//thirdparty:xxx                                     # Application code depends on this target

5.3.2 Register External Repositories

All tri-banks are stored in one place./sdk/dev_tools/third_party_libs/external/Down, through. /sdk/dev_tools/sdk-buildchain/projects/external/sdk_third_party_deps.bzl Mediumlocal_repositoryRegister:

  • The source-based library registers a warehouse, compiled by Bazel according to the current tool chain, which naturally supports multistructures
  • The pre-record is registered by structure and the name of the warehouse is as follows:_x86_64 / _aarch64End
java
def third_party_deps():
    # Source Build: Single Repository
    native.local_repository(
        name = "jsoncpp",
        path = "/sdk/dev_tools/third_party_libs/external/jsoncpp",
    )

    # Pre-compiled: one warehouse per structure
    native.local_repository(
        name = "boost_x86_64",
        path = "/sdk/dev_tools/third_party_libs/external/boost_x86_64",
    )
    native.local_repository(
        name = "boost_aarch64",
        path = "/sdk/dev_tools/third_party_libs/external/boost_aarch64",
    )

5.3.3 Unified Entry Point

Pass./sdk/dev_tools/sdk-buildchain/BUILDMediumaliasExternal exposure of names not related to structure, pre-recording libraryselectSwitch automatically to target platform:

bash
# Pre-enactment: selection by structure
alias(
    name = "boost",
    actual = select({
        "@integration//toolchains/platforms:is_aarch64": "@boost_aarch64//:boost",
        "//conditions:default": "@boost_x86_64//:boost",
    }),
    visibility = ["//visibility:public"],
)

# Source build: directly forward
alias(
    name = "jsoncpp",
    actual = "@jsoncpp",
    visibility = ["//visibility:public"],
)

5.3.4 Forward Dependencies to the Application Repository

aimdk_examples/thirdparty/BUILDThe following is a retransmission, and the tri-bureau used in this warehouse is clear:

python
alias(
    name = "boost",
    actual = "@integration//:boost",
)

alias(
    name = "jsoncpp",
    actual = "@integration//:jsoncpp",
)

The business code depends on it.//thirdparty:xxx:

python
cc_binary(
    name = "demo",
    srcs = ["main.cc"],
    deps = [
        "//thirdparty:boost",
        "//thirdparty:jsoncpp",
    ],
)

5.3.5 Add a Third-Party Library

  1. Place library files in/sdk/dev_tools/third_party_libs/external/(Pre-Book catalogue by structure)
  2. Yes.sdk_third_party_deps.bzlUseablelocal_repositoryRegistration
  3. Yes.integration/BUILDAddalias(to be used in the pre-record library)select)
  4. It's in the business room.thirdparty/BUILDCannot initialise Evolution's mail component.alias

Do not rely directly on the code.@xxx、@xxx_x86_64、@xxx_aarch64or@integration//:xxxUnanimously.//thirdparty:xxxQuote. When the source or structure of such reliance changes, you need only change the definition upstream and the business code does not change.

5.4 SDK Dependency Description

All SDKs rely on pre-integrated local development environment (aimde) for integrated management through Bazel. Users do not need to download the installation manually, but simply use it as required in the business code.

**Note:**The SDK refers to the header (.h) and dynamic library (.so) where the internal code of the Idea is exposed, and does not include external tripartite dependence.

5.4.1 Architecture Path Definitions

Specify SDK paths for different structures through YAML configuration file:

x86_64 architecture: /sdk/dev_tools/sdk-buildchain/projects/sdk_defs/x86_64.yaml

python
sdk:
  local:
    path: /sdk/dev_tools/x86_64/

RK3588 architecture:/sdk/dev_tools/sdk-buildchain/projects/sdk_defs/rk3588_aarch64.yaml

python
sdk:
  local:
    path: /sdk/dev_tools/rk3588_aarch64/

5.4.2 SDK Repository Structure

plain
/sdk/dev_tools/{x86_64|rk3588_aarch64}/
    ├── aimdk/                              # Header files generated from Protobuf protocols
    ├── aimrte/                             # HDS header files
    ├── all_plugins/                        # Plugin libraries (mqtt_plugin/ros2_plugin/net_plugin, etc.) and dependencies
    ├── BUILD                               # Bazel target definitions for SDK libraries
    ├── google/                             # Common Google Protobuf headers (such as any.pb.h)
    ├── libzy_aimrt_comm.so                 # aimrt_comm API shared library
    ├── libzy_aimrt.so                      # aimrt API shared library
    ├── ros2/                               # Headers generated from ROS2 protocols
    ├── src/                                # Core headers (aimrt/aimrt_comm/)
    └── WORKSPACE                           # Bazel WORKSPACE file for the SDK repository

5.4.3 Core Libraries

Library nameFunction Description
libaimrtCore library when running, providing basic running time functions (networks, configurations, etc.)
libaimrt_commCommunication layer library with Protobuf/ROS2 protocols and generic tools
libhealth_diag_generationHealth diagnostic library, which provides modular health surveillance functions
all_pluginsPlugin collection (mqtt\plugin/ros2plugin et al.)

5.4.4 BUILD Definition Example

python
# Export all SDK resources
package(default_visibility = ["//visibility:public"])
exports_files(glob(["**/*.h*", "**/*.inl", "**/*.so*"]))

# Core library definition
cc_library(
    name = "libaimrt",
    includes = [
        "src/protocols/plugins/ros2_plugin_proto/common/msg",
    ],
    srcs = ["//:libzy_aimrt.so"],
    hdrs = [
        "src/common/net/asio_http_cli.h",
        "src/runtime/core/util/yaml_tools.h",
        # ...
    ],
    linkopts = [
    ],
    defines = [
        "BOOST_ASIO_NO_DEPRECATED",
        "AIMRT_USE_FMT_LIB"
    ],
)

cc_library(
    name = "libaimrt_comm",
    includes = ["ros2/data_proxy", "ros2/audio/StopAudioPlay", ...],
    srcs = ["libzy_aimrt_comm.so"],
    hdrs = [
        "aimdk/protocol/action/arm.pb.h",
        "ros2/audio/audio_msgs/msg/volume_type.h",
        "src/all_in_one/include/aimrte.h",
        # ...
    ],

    deps = [
        "@boost_x86_64//:boost",
        "@ros2_common_interfaces//:cpp_geometry_msgs",
        "@sdk//:libaimrt",
        "@sdk//:libhealth_diag_generation",
        # ...
    ],
    defines = ["AIMRT_USE_FMT_LIB"],
)
...

cc_library(
    name = "libhealth_diag_generation",
    srcs = [

    ],
    hdrs = glob(["aimrte/hds/**/*.h"]),
    deps = [

    ],
    linkopts = [

    ],
    defines = [

    ],
)

filegroup(
    name = "all_plugins",
    srcs = glob(["all_plugins/**"]),
)

cc_library(
    name = "agibot_sdk",
    deps = [
        ":libaimrt_comm",
    ],
)

5.4.5 Use SDK Dependencies in the Application Repository

Introduce SDK Dependence

Pass."//thirdparty:agibot_sdk"Direct quote:

python
package(default_visibility = ["//visibility:public"])

cc_library(
    name = "aimdk_example_module",
    srcs = glob([
        "*.cpp",
    ]),
    hdrs = glob([
        "*.h",
    ]),
    deps = [
        "//thirdparty:agibot_sdk",
    ],
)

Plugin Introduction

Yes.pkg_tarIt's... it's... it's...depsMedium pass.@integration//:all_plugins_tarPacking:

python
pkg_tar(
    name = "aimdk_example_tar",
    srcs = [
    ],
    extension = "tar",
    mode = "0755",
    strip_prefix = ".",
    tags = ["tar"],
    include_runfiles = True,
    deps = [
        ...
        "@integration//:all_plugins_tar",
        ...
    ],
)

5.5 Module Development

5.5.1 AimRT Module

AimRT is a communication and running time frame for robotic scenes. The developers write business logicModule, by application (App) loaded into the process by means of communication (Channel release/subscription, RPC), thread (Execctor), log, plugin etc.YAML ProfileDecides that the business code is decoupled from the specific communications backend (iceoryx / ROS2 / HTTP, etc.).

This post is part of our special coverage Syria Elections 2011.aimdk_examples/examples/aimrt/aimdk_examplesFor example, explain how to use it on the basis of AimDKAimRTFramework preparation, compilation and operation of a custom module.

Contents structure

plain
examples/aimrt/aimdk_examples/
├── app/
│   └── aimdk_example/
│       ├── main.cpp                       # Program entry point; registers the module
│       └── BUILD                          # Executable and packaging rules
├── module/
│   └── aimdk_example/
│       ├── aimdk_example.h                # Module declaration
│       ├── aimdk_example.cpp              # Module implementation
│       └── BUILD                          # Module library (cc_library)
├── config/
│   └── aimdk_example/
│       ├── aimdk_example_config.yaml      # AimRT runtime configuration
│       └── BUILD
└── scripts/
    └── aimdk_example/
        ├── start_aimdk_example.sh         # Startup script
        └── BUILD

Repository root directoryBUILDMediumaimdk_example_tarResponsible for final installation of configurations, plugins, executables and start-up scriptsbazel-bin/aimdk_example_tar.tar。

examples/native/Next is the example of the original C++/ Python, which is not dependent on the SimRT module frame, which has nothing to do with this paper.

5.5.1.1 Implement the Module

Module Header Files(module/aimdk_example/aimdk_example.h)

c++
#pragma once#include "audio_msgs/msg/audio_capture.hpp"#include "src/all_in_one/include/aimrte.h"namespace aimdk_examples::module::aimdk_example {

class AimdkExampleModule : public aimrte::ctx::ModuleBase {
 public:
  struct Option {
    aimrte::Sub<audio_msgs::msg::AudioCapture> audio_capture_sub{"/audiohal/audio/capture"};
  };

 public:
  AimdkExampleModule();
  ~AimdkExampleModule() override;

  bool OnInitialize() override;
  bool OnStart() override;
  void OnShutdown() override;

  void ReceiveAudioCapture(const std::shared_ptr<const audio_msgs::msg::AudioCapture>& msg);

 private:
  Option option_;
};

}  // namespace aimdk_examples::module::aimdk_example

Highlights:

  • You just have to introduce it.src/all_in_one/include/aimrte.h, you can use the AimRT packageaimrte::Interface.
  • Message type from the AimDK package (using ROS2 messages here)audio_msgs::msg::AudioCapture)。
  • Focus on resources such as subscribersOptionIn structure:
    • aimrte::Sub<T>: a subscription handle for a topic;
    • If you need to move back in a separate thread pool, you can copy it.aimrte::ExeDeclaration executor.

Module realization(module/aimdk_example/aimdk_example.cpp)

c++
bool AimdkExampleModule::OnInitialize() {
  option_.audio_capture_sub = aimrte::ctx::init::Subscriber<audio_msgs::msg::AudioCapture>("/audiohal/audio/capture");
  option_.audio_capture_sub.WhenInit().SubscribeInline(std::bind(&AimdkExampleModule::ReceiveAudioCapture, this, std::placeholders::_1));
  return true;
}

bool AimdkExampleModule::OnStart()    { return true; }
void AimdkExampleModule::OnShutdown() {}

void AimdkExampleModule::ReceiveAudioCapture(const std::shared_ptr<const audio_msgs::msg::AudioCapture>& msg) {
  AIMRTE_INFO("stamps: sec={}, nanosec={}", msg->stamps.sec, msg->stamps.nanosec);
  AIMRTE_INFO("mic_channels: {}", msg->mic_channels);
  AIMRTE_INFO("ref_channels: {}", msg->ref_channels);
  AIMRTE_INFO("info: channels={}, sample_rate={}, sample_format={}, coding_format={}",
              msg->info.channels, msg->info.sample_rate, msg->info.sample_format, msg->info.coding_format);
  AIMRTE_INFO("data: {} bytes", msg->data.data.size());
}

Module life cycle:

Turn back.TimingTypical uses
OnInitialize()Initialization phaseCreate subscriber/issuer/RPC client and service, read configuration; returns false for initialization failed
OnStart()Start-up phaseStart the business cycle, scheduled tasks, etc.
OnShutdown()Stop phaseRelease of resources

Subscriptions:SubscribeInline(callback)If you need to process a time-consuming logic in a specified thread pool, you canOptionOne of them.aimrte::ExeExecutor (and config file)aimrt.executor. Please refer to the AimRT official document and the AimDK header file.

Log UseAIMRTE_INFO(...)({}Formatting style), log level by profileaimrt.logControl.

5.5.1.2 Module BUILD (module/aimdk_example/BUILD)

python
cc_library(
    name = "aimdk_example_module",
    srcs = glob(["*.cpp"]),
    hdrs = glob(["*.h"]),
    deps = [
        "//thirdparty:agibot_sdk",   # AimDK/AimRT headers and libraries
    ],
)

//thirdparty:agibot_sdkReliance on the AimRT and AimDK protocols is provided, and the module can only rely on it.

5.5.1.3 Implement the Application Entry Point (app/aimdk_example/main.cpp)

c++
#include <iostream>#include "examples/aimrt/aimdk_examples/module/aimdk_example/aimdk_example.h"int main(int argc, char** argv) {
  std::cout << "Hello, AIMDK!" << std::endl;

  aimrte::Cfg cfg(argc, argv, "aimdk_example");
  return aimrte::Run(cfg, {{"AimdkExampleModule", std::make_shared<aimdk_examples::module::aimdk_example::AimdkExampleModule>()}});
}
  • aimrte::CfgParsing command line parameters (started scripted)--cfg_file_path=...)。
  • aimrte::RunReceive the mapping and operation of the module name to the module example;"AimdkExampleModule"It is a modular name that needs to be aligned with the configuration of the module in the configuration document.
  • If multiple modules are required, continue to add to the map.

app/aimdk_example/BUILDMediumcc_binaryReliance on the modules library and turn executables, configurations, start-up scripts into installation packages:

python
cc_binary(
    name = "aimdk_example",
    srcs = ["main.cpp"],
    deps = ["//examples/aimrt/aimdk_examples/module/aimdk_example:aimdk_example_module"],
)

5.5.1.4 Configuration File (config/aimdk_example/aimdk_example_config.yaml)

Configure file to determine run-time behaviour, main paragraph:

ParagraphRoleThis is the case.
aimrt.configuratorConfiguration, temp\cfg_path Configure the storage path for temporary modules../config/aimdk_example/tmp
aimrt.pluginLoad Pluginsnet_plugin、ros2_plugin、iceoryx_plugin
aimrt.logLog Levelcore_lvl: INFO,default_module_lvl: Info
aimrt.executorExecutor (hide pool)work_thread_pool(4)、timeout_handle(2)
aimrt.channelChannel Backend and Topic OptionsBackend icoryx, ros2; /audiohal/audio/capture only is enabled ros2 (radiohal releases this topic through ROS2, consistent with the original example)
aimrt.rpcRPC Backendhttp、ros2

Topic and backend needs for code subscriptions withchannelparagraph matches; if a new executor is added, the executor name must be firstaimrt.executorIt's in the code. It's in the code. It's in the code.aimrte::Exe{"name"}Quote.

5.5.1.5 Startup Script and Packaging

Start Script Asscripts/aimdk_example/start_aimdk_example.sh. Pass on startup.--cfg_file_pathPass in.

5.5.1.6 Build and Run

See complete steps for compilation, local operation, deployment to equipment, debuggingBuild and Deployment, the goal of this case is calledaimdk_example:

bash
bash tools/build_module.sh -t aimdk_example -a x86_64
bash tools/run_module.sh -t aimdk_example

When running successfully, the module will be received/audiohal/audio/captureThe time stamp, the number of microphones and reference channels, the logs for sampling information and data length when the message is exported.

5.5.1.7 Add a Custom Module

Add with new modulefooFor example:

  1. Create Module: Newmodule/foo/foo.h、foo.cppInheritance.aimrte::ctx::ModuleBaseAnd it's happening.OnInitialize / OnStart / OnShutdown。
  2. Module BUILD: Simulationmodule/aimdk_example/BUILDAddcc_library(e.g.)foo_moduleReliance.//thirdparty:agibot_sdk。
  3. Registration module: Inapp/aimdk_example/BUILDIt's... it's... it's...cc_binary.deps_Other Organiser//examples/aimrt/aimdk_examples/module/foo:foo_module(or create a new one by reference to the BUILD)app/foo/BUILD); inmain.cppMedium#includeHeader file, andaimrte::RunAdding to the map{"FooModule", std::make_shared<...::Foo>()}。
  4. Update Configuration: If new executor, topic backend options, plugins are added to the YAML corresponding paragraph.
  5. Build and run

5.5.1.8 Common Communication Patterns

  • Release / RPC: Interface is also throughaimrte::ctx::init::Yes.OnInitialize_Other Organisersrc/all_in_one/include/aimrte.h。
  • Do not use the AimRT module frametopic/RPC, referenceexamples/native/cppandexamples/native/python。

5.5.1.9 Common Issues

  • Start and exit / Initialization failed: InspectionOnInitializeWhether or not to returntrue, and whether the executor and topic used in the code are configured in YAML.
  • I can't hear you.: confirm that the distribution end is the same topic as the subscription and the same backend (this case subscription is only enabled)ros2) and on the equipmentaudiohalThe corresponding service is running.
  • Adjust Log: Modifying configurationaimrt.log.core_lvl / default_module_lvl。
  • Debug: Usestart_aimdk_example.sh -g -p <port>Starts with lldb-server and connects remotely.

5.5.2 Native C++ Development

This post is part of our special coverage Syria Elections 2011.aimdk_examples/examples/native/cppExamples of catalogues,Do not use the AimRT module frame, but as an independent process, directly interacts with robotic services through ROS2 or HTTP. Each example is independent.cc_binary, which can be compiled, packaged and run separately.

5.5.2.1 Directory Structure

Each example catalogue is structured consistently:

plain
cpp/
├── channel/<name>/
│   ├── <name>.cpp             # Example source code
│   ├── start_<name>.sh        # Startup script
│   └── BUILD                  # Executable and packaging rules
└── rpc/<name>/
    ├── <name>.cpp
    ├── start_<name>.sh
    └── BUILD

5.5.2.2 Channel Examples

Could not close temporary folder: %s:heart_beat、tts_status

The two examples have the same structure and only topic differs from the message type:

Example:TopicProtobuf Type
heart_beat/aima/heartbeat/pb_3Aaimdk_2Eprotocol_2EProcessHeartbeatChannelaimdk::protocol::ProcessHeartbeatChannel
tts_status/interaction/tts_status/pb_3Aaimdk_2Eprotocol_2ETTSStatusaimdk::protocol::TTSStatus
Highlights:
  • Use it.rclcpp::NodeSubscriptionsros2_plugin_proto::msg::RosMsgWrapper. The message is the encapsulation of the EmRT ROS2 plugin for protobuf,serialization_typeYes."pb"It's a long time ago.datais the bytes after the protobuf has been sequenced.
  • Let's get back to it.serialization_type == "pb"Again.ParseFromArrayReverse sequence to specific protobuf messages, last usedMessageToJsonStringConverts to JSON output.
  • From Topic Namepb_3Aaimdk_2Eprotocol_2E...is the full name of the protobuf type (pb:aimdk.protocol.…) the result of the transliteration of the ROS2 name (: → _3A,. → _2E)。
  • QoS UseKeepLast(10) + best_effort。
c++
rclcpp::QoS qos_profile(rclcpp::KeepLast(10));
qos_profile.best_effort();
subscription_ = create_subscription<ros2_plugin_proto::msg::RosMsgWrapper>(
    topic_name_, qos_profile, std::bind(&Xxx::Callback, this, std::placeholders::_1));

5.5.2.3 Subscribe to ROS2 Messages

Subscribe ROS2 messages:joint_state、audio_capture

Example:TopicMessage TypeSources
joint_state/motion/control/arm_joint_statesensor_msgs::msg::JointStateROS2 standard message
audio_capture/audiohal/audio/captureaudio_msgs::msg::AudioCapture
AimDK Customise ROS2 Message
Direct subscription to ROS2 message type, field printing in echoes (joint_statePrint header / name / position / vulocity / effort;audio_capturePrint time stamp, number of microphones and reference channels, length of sample information and data).

audio_msgsNot ROS2 self-carried packages, but an AimDK-defined message package, which requires an AimDK-loaded ROS2 message package in the running environment (start scripts will be loaded)/agibot/software/v0/entry/env/env.sh. The same package.audio_msgs::srv::AbandonAudioFocusIt's also a custom service.

5.5.2.4 RPC Examples

HTTP + JSON:GetArmJointState、GetAction

Example:URLType of request / response
GetArmJointStatehttp://10.42.10.12:56322/rpc/aimdk.protocol.MotionControlJointService/GetArmJointStateCommonRequest / JointStateResponse
GetActionhttp://10.42.10.12:56322/rpc/aimdk.protocol.MotionControlActionService/GetAction
CommonRequest / MotionControlActionResponse

These two examples send POST requests via libcurl to the HTTP RPC interface for robotic services:

URL rules:http://<device-ip>:<port>/rpc/<fully-qualified-protobuf-service>/<method>。

Call the process (same examples):

  1. Construct protobuf request, useMessageToJsonStringTurn to JSON;
  2. curlByContent-Type: application/jsonPOST to the corresponding URL, 5 seconds longer;
  3. Check the curl return code and the HTTP status code (up to 200);
  4. Use it.JsonStringToMessage(ignore_unknown_fields = true) parsing the response and formatting the output.

Error printing to stderr and ending with exit code 1 when any step fails.

SetAudioVolumeA volume parameter is required, the request is fixedis_mute = false、type = SPEAKRE_BUILT_IN(internal speaker):

bash
./SetAudioVolume 50

Device IP (in code)10.42.10.12、10.42.10.10) is hard-coded, if the network of equipment requires a change in the source codekUrlRecompiled later.

5.5.2.5 ROS2 Service:AbandonAudioFocus

  • Service name:/audio_5Fmsgs/srv/AbandonAudioFocus(AimDK custom service)audio_msgs::srv::AbandonAudioFocus,_5FYes._It's the transition.
  • Process: create clit ~ cycle per 2 secondswait_for_serviceUntil service is available Fillfocus_requester(pkg_name = "aimdk_examples"、priority = 6、priority_weight = 1)→ async_send_request → spin_until_future_completePrintpkg_nameandfocus_gain。
  • Use on exitstd::_ExitJust finish the process. Don't do it.rclcpp::shutdown. The source comment explains why:rclcpp::NodeParsing triggered DDS participant destruction with agibot\sdk autobandlibzy_aimrt.soThe internal aso schiduler has a symbol conflict that will be used for the exit phase. This applies only to this type of one-time call tool, and the permanent application is not copied.

5.5.2.6 BUILD Dependencies

Example typeDependence
Channel (4)/thirdparty: cpp\rclcpp; heart\beat, tttsstatus //thirdparty:protobuf, /thirdparty: agibot\sdk
HTTP RPC (4)//thirdparty:CURL、//thirdparty:protobuf、//thirdparty:agibot_sdk
AbandonAudioFocus//thirdparty:cpp_rclcpp、//thirdparty:agibot_sdk

Every one.BUILDDividecc_binaryIn addition, there are three packing targets:

  • <name>_script: Put it on.start_<name>.shPut it on.scripts/<name>/;
  • <name>_without_bin_tar: only scripts;
  • <name>_bin_flatten_tar: executable and dependent, put onbin/。

Root DirectoryBUILDMedium<name>_tarMerge the two parts into a final installation package.

5.5.2.7 Build

build_module.sh -t <name>It's built.<name>_tarAnd so...-tSend the example name directly:

bash
# x86
bash tools/build_module.sh -t heart_beat -a x86_64

# ARM
bash tools/build_module.sh -t heart_beat -a rk3588_mdu_aarch64
bash tools/build_module.sh -t heart_beat -a rk3588_hdu_aarch64

Available-tValue:heart_beat、tts_status、joint_state、audio_capture、GetArmJointState、GetAction、GetAudioVolume、SetAudioVolume、AbandonAudioFocus。

The product is...bazel-bin/<name>_tar.tar。

5.5.2.8 Run

Local(x86, aimde environment)

bash
bash tools/run_module.sh -t heart_beat

On the device.

After transmitting and decompressing the installation package, use start-up scripts:

bash
bash /agibot/data/ggm/scripts/heart_beat/start_heart_beat.sh

Start script will enter../../binLoad/agibot/software/v0/entry/env/env.sh(or)/opt/ros/jazzy、/opt/ros/humble) the environment, then the executable file is activated and the Ctrl+C (SIGINT/SIGTERM) exits elegantly.

Common parameters:

ParametersAnnotations
-g, --debugRun in ldb-server debug mode
-p, --portDebug port (default 65001)
-h, --helpHelp

start_SetAudioVolume.shI'm gonna need another one.-v, --volume <volume>(Necessary):

bash
bash scripts/SetAudioVolume/start_SetAudioVolume.sh -v 50

5.6 Build and Deployment

This document is a compilation, local operation, and deployment process common to the SimRT module and the original C++ example. Both are done through the same script, the difference being only -t's entry target name.

Target name_tar in BUILD, produced by bazel-bin/_tar.tar.

CategoryAvailable
AimRT Moduleaimdk_example
Original C++ Channelheart_beat、tts_status、joint_state、audio_capture
Original C++ RPCGetArmJointState、GetAction、GetAudioVolume、SetAudioVolume、AbandonAudioFocus

tools/build_module.sh -t <name>Build root directoryBUILDMedium<name>_tar, the product is...bazel-bin/<name>_tar.tar。

The following is a reference:aimdk_exampleFor example, replace them with other target names.

5.6.1 Build

Select architecture based on target equipment:

bash
# ARM - mdu
bash tools/build_module.sh -t aimdk_example -a rk3588_mdu_aarch64

# ARM - hdu
bash tools/build_module.sh -t aimdk_example -a rk3588_hdu_aarch64

# x86
bash tools/build_module.sh -t aimdk_example -a x86_64

Compiled products:bazel-bin/aimdk_example_tar.tar

build_module.shParameters:

ParametersAnnotations
-tTarget name (which must be filled)
-aArchitecture: x8664 (default), rk3588mduaarch64, rk3588hduaarch64
-jNumber of simultaneous compilation and translation tasks
-gDebug compilation (-copt=-g-copt=-O0)
-cBazel clean-expunge before compilation
-eAppend bazel options, such as -e " --config=xx"

Local Run (x86)

x86 The compiler can run directly in the aimde environment:

bash
bash tools/run_module.sh -t aimdk_example

run_module.shI'll take it.bazel-bin/<name>_tar.tarUnplugged.bazel-bin/<name>_tar/I'll do it again.scripts/<name>/start_<name>.sh。

Parameters:

ParametersAnnotations
-tTarget name (which must be filled), completion of x86 compilation
-cCustomise the absolute path of the profile file, only AimRT module available (startup script for original example not accepted -c)
-gDebug Mode
-pDebug port (effective -g)

Example:bash tools/run_module.sh -t aimdk_example -c $(pwd)/examples/aimrt/aimdk_examples/config/aimdk_example/aimdk_example_config.yaml

run_module.shCould not close temporary folder: %sSetAudioVolumeYes.-v <volume>, enter the decompression directory to run the start-up script directly:

bash
bash bazel-bin/SetAudioVolume_tar/scripts/SetAudioVolume/start_SetAudioVolume.sh -v 50

5.6.2 Deploy to the Target Device

Pre-deployment request to ensure that the structure of the target equipment used corresponds to the structure (rk3588_mdu_aarch64orrk3588_hdu_aarch64) Completion of the compilation.

IP, account number, table of contents below are taken from the Example Environment and should be replaced with actual equipment.

5.6.2.1 Transfer the Installation Package

bash
sshpass -p 1 scp \
  -o UserKnownHostsFile=/dev/null \
  -o StrictHostKeyChecking=no \
  -o ConnectTimeout=120 \
  -P 22 \
  bazel-bin/aimdk_example_tar.tar \
  agi@192.168.111.140:/agibot/data/ggm/

5.6.2.2 Log In to the Device and Extract

bash
ssh agi@192.168.111.140 -p 22
bash
cd /agibot/data/ggm
tar -xvf aimdk_example_tar.tar
rm aimdk_example_tar.tar

5.6.2.3 Start

bash
bash /agibot/data/ggm/scripts/aimdk_example/start_aimdk_example.sh

5.6.2.4 Package Layout and Startup Script

The decompressed directory (for example, the AimRT module):

plain
bin/                              # Executable and dependencies; AimRT modules also include plugins
config/aimdk_example/             # Configuration file (AimRT modules only)
scripts/aimdk_example/            # Startup script

Original C++ example installation package onlybin/andscripts/<name>/No, I didn't.config/。

Start Scriptscripts/<name>/start_<name>.shConduct:

  1. Enter../../bin;
  2. Loading Environment: Priority/agibot/software/v0/entry/env/env.sh, second/opt/ros/jazzy、/opt/ros/humble;
  3. Start executable;AimRT module extra input--cfg_file_path=<configuration-file>;
  4. Capture SIGINT / SIGTERM and exit elegantly (wait at most 30 seconds, kill over time).

Start script parameters:

ParametersApplicationAnnotations
-c, --configAimRT module onlyCustom profile (absolute path), default . ./config/aimdk\example/aimdk\example\config.yaml
-g, --debugAllRun in ldb-server debug mode
-p, --portAllDebug port, default 65001
-h, --helpAllHelp

5.6.2.5 Debugging

  1. Use it.-gCompile (with debugging symbols, off optimization):
bash
bash tools/build_module.sh -t aimdk_example -a rk3588_mdu_aarch64 -g
  1. Start with debug mode after deployment by lldb-server listening port:
bash
bash /agibot/data/ggm/scripts/aimdk_example/start_aimdk_example.sh -g -p 65001
  1. Connects the port remotely on the developer using the lldb.

5.6.2.6 Common Issues

  • Target tar does not exist: no x86 compilation of the corresponding target completed before running, execute firstbuild_module.sh -t <name> -a x86_64。
  • Unable to run after deployment/ structure mismatch: Confirming compilation-aConsistent with the equipment model (mdu/ hdu), x86 products cannot be deployed to the equipment.
  • Unsupported ARCH_TYPE:-aSupport onlyx86_64、rk3588_mdu_aarch64、rk3588_hdu_aarch64。
  • Native example passed.-cWrong report.:-cOnly for the AimRT module.

5.7 Python Packaging and Deployment

This post is part of our special coverage Syria Elections 2011.aimdk_examples/examples/native/pythonHere's an example under the directory, too.Do not use the AimRT module frame, as a stand-alone script through ROS2rclpy) or HTTP(requests) Interacts with robotic services. The Python example is not compiled by Bazel. Runs directly with the Python interpreter.

5.7.1 Directory Structure

plain
python/
├── pyproject.toml             # Project dependencies (aimdk-proto, protobuf, requests; see Section 3.3)
├── uv.lock                    # Dependency lock file (single source of truth)
├── requirements.txt           # Intermediate file exported from uv.lock
├── .venv-x86/ .venv-rk3588/   # Virtual environments for each chip (prebuilt before SDK release)
├── channel/
│   └── <name>/{<name>.py, start_<name>.sh}
└── rpc/
    └── <name>/{<name>.py, start_<name>.sh}

5.7.2 Channel Examples

Could not close temporary folder: %s:heart_beat、tts_status

Example:TopicProtobuf Type
heart_beat/aima/heartbeat/pb_3Aaimdk_2Eprotocol_2EProcessHeartbeatChannelaimdk::protocol::ProcessHeartbeatChannel
tts_status/interaction/tts_status/pb_3Aaimdk_2Eprotocol_2ETTSStatusaimdk::protocol::TTSStatus
Highlights:
  • Script Directfrom aimdk.protocol.xxx import xxx_pb2Import, these modules are installed in a virtual environment without any needsys.pathDeal.
  • Subscriptionsros2_plugin_proto.msg.RosMsgWrapper;checking in returnserialization_type == "pb"Again.ParseFromString(b"".join(msg.data))Reverse Sequencing, Final UseMessageToJsonOutput.
  • QoS:KEEP_LASTDepth 10,BEST_EFFORT。
  • Topic name is the result of a transposition of the protobuf type with the ROS2 name: → _3A,. → _2E)。

Subscribe custom ROS2 messages:audio_capture

Subscriptions/audiohal/audio/capture(AimDK customise ROS2 messages)audio_msgs.msg.AudioCapture, non-ROS2 standard message), print time stamp, number of microphones and reference channels, sample information and length of data.

Four Channel scripts.try/except (KeyboardInterrupt, ExternalShutdownException)Process Ctrl+C, andfinallyMediumdestroy_nodeandrclpy.shutdown()。

aimdk.protocol.*protobuf binding (aimdk-proto(Backloads)

heart_beat、tts_statusIt's used.aimdk.protocol.*_pb2Module provided by SDKaimdk-protoHere's the package. It's been declared inpyproject.tomlReliance. When you build a virtual environment, it's automatically installed, and when you write the code, it's direct.import, no additional configuration is required.

Module path rules:aimdk.protocol.<subdirectories...>.<file-name>_pb2Corresponds to the AimDK protocol.protoThe catalogue structure of documents corresponds to one another, for example:

Protobuf TypeImport by
ProcessHeartbeatChannelfrom aimdk.protocol.hds.process import process_heartbeat_channel_pb2
TTSStatusfrom aimdk.protocol.interaction import tts_service_pb2

If you want to use other messages, just use the same rules to import them.

5.7.3 RPC Examples

Example:URL
GetArmJointStatehttp://10.42.10.12:56322/rpc/aimdk.protocol.MotionControlJointService/GetArmJointState
GetActionhttp://10.42.10.12:56322/rpc/aimdk.protocol.MotionControlActionService/GetAction

Userequests.post(URL, json=payload, timeout=5)Call robot HTTP RPC interface, print formatted after success

  • URL rules:http://<device-ip>:<port>/rpc/<fully-qualified-protobuf-service>/<method>。
  • Query Interface Request is an empty object{};SetAudioVolumeThe request is:
python
{"audio_volume": int(sys.argv[1]), "is_mute": False, "type": "SPEAKRE_BUILT_IN"}
  • Request for abnormal or HTTP status code not 2x(s)raise_for_status) , output error to stderr and returns exit code 1.
  • Python version uses the JSON dictionary directly and does not rely on protobuf to generate code; like C++ version, device IP is hard coded and the network does not have to be modified at the same timeURL。

ROS2 Service:AbandonAudioFocus

  • Service name/audio_5Fmsgs/srv/AbandonAudioFocus(AimDK custom service)audio_msgs.srv.AbandonAudioFocus)。
  • Process: create client ~ every 2 secondswait_for_serviceUntil available fillfocus_requester(pkg_name = "aimdk_examples"、priority = 6、priority_weight = 1)→ call_async → spin_until_future_completePrintpkg_nameandfocus_gain。
  • Python doesn't need to be a Python, unlike C++._ExitEvacuate exit crash, normal.destroy_node + shutdownAll right.

5.7.4 Python Environment Requirements

Dependencies (pyproject.toml, request Python § 3.10:

  • aimdk-proto(protobuf Python of the AimDK protocol, supplied with SDK environment)
  • protobuf>=6.31,<7♪ Can't be less than ♪aimdk-protoVersion for Generating Code)
  • requests>=2.34.2

rclpy、sensor_msgs、audio_msgs、ros2_plugin_protoWaiting for ROS2 packages not in this dependency, but from the system ROS2/AimDK environment (virtual environment)--system-site-packagesCreates, reuses the system package.

Virtual environment of each chip..venv-x86、.venv-rk3588) has been constructed with SDK, is ready for direct use and does not need to be self-installed.

5.7.5 Package the Runtime Environment

bash
bash tools/package_python_env.sh -c rk3588
# Default output desist/ aimdk_examples_python_env-rk3588.tar.gz, available -o specification

When packing, the source code is copied to the temporary folder, only the virtual environment of the target chip is preserved and renamed..venv(So starting in script).venv/bin/python3And clean it up at the same time.pycache, and delete the invalid script of the path of the shebang to the dead machine.

5.7.6 Run

5.7.6.1 Local

On machines with ROS2 environments, enter the list of examples and run with start-up scripts:

bash
cd examples/native/python/channel/heart_beat
bash start_heart_beat.sh

Example RPC:

bash
cd examples/native/python/rpc/SetAudioVolume
bash start_SetAudioVolume.sh -v 50

Activate script:

  1. Load ROS2 Environment: Priority/agibot/software/v0/entry/env/env.sh, second/opt/ros/jazzy、/opt/ros/humble;
  2. For example for AimDK messages, extrasourceCorrespondinglocal_setup.bash:heart_beat、tts_statusLoadros2_plugin_proto,audio_capture、AbandonAudioFocusLoadaudio_msgs;
  3. Priority Usepython/.venv/bin/python3, return to system if not foundpython3;
  4. Run.pyScript, and handle SIGINT/SIGTERM exits elegantly (at most 30 seconds).

start_SetAudioVolume.shYes.-v, --volume <volume>Other scripts only support-h。

5.7.6.2 Deploy to the Device

  1. Pack it against the chip's operating environment. Got it.aimdk_examples_python_env-<chip>.tar.gz;
  2. Copy to device and depress:tar -xzf aimdk_examples_python_env-rk3588.tar.gzGot it.python/Contents;
  3. Enterpython/channel/<name>orpython/rpc/<name>, Runstart_<name>.sh。