2. 使用ara

任务说明

本案例目标是在AUTOSAR Adaptive平台中,通过ara::com运行时定义并发布一个服务接口。我们将实现一个最小可复现的示例:定义RadarService服务接口(包含一个方法Detect和一个事件TargetList),完成服务端注册与客户端代理创建,并验证服务发现与调用链路。

服务接口定义(ARXML)

首先通过ARXML描述服务接口的骨架,这是ara::com代码生成器的输入。以下为精简后的接口定义:

<?xml version="1.0" encoding="UTF-8"?>
<interface>
  <service-interface>
    <name>RadarService</name>
    <version>1.0.0</version>
    <method>
      <name>Detect</name>
      <input>DetectionRequest</input>
      <output>DetectionResponse</output>
    </method>
    <event>
      <name>TargetList</name>
      <type>TargetArray</type>
    </event>
  </service-interface>
</interface>

实际工程中,此ARXML会通过ara::com代码生成器(如generator工具)生成C++代理/骨架类。本案例聚焦运行时使用,故直接使用生成后的API进行编码。

服务端实现(骨架)

#include <ara/com/ServiceSkeleton.h>
#include <ara/com/ServiceSkeletonBase.h>
#include "RadarService_skeleton.h"  // 由ARXML生成

class RadarSkeletonImpl : public RadarServiceSkeleton {
public:
    RadarSkeletonImpl(ara::core::InstanceSpecifier spec)
        : RadarServiceSkeleton(spec) {}

    // 实现方法Detect
    ara::core::Future<DetectionResponse> Detect(
        const DetectionRequest& request) override {
        DetectionResponse resp;
        resp.valid = true;
        resp.target_count = 3;
        // 实际处理逻辑...
        return ara::core::Promise<DetectionResponse>::FromValue(resp);
    }

    // 事件发送示例
    void SendTargets() {
        TargetArray targets;
        targets.targets = {{100.0, 20.0}, {150.0, -10.0}};
        TargetList.Send(targets);  // 触发事件
    }
};

int main() {
    ara::core::InstanceSpecifier spec("RadarService/RadarSkeleton");
    RadarSkeletonImpl service(spec);
    service.OfferService();  // 启动服务发现
    // 进入事件循环(示例中省略)
    return 0;
}

客户端实现(代理)

#include <ara/com/ServiceProxy.h>
#include "RadarService_proxy.h"  // 由ARXML生成

void ClientExample() {
    ara::core::InstanceSpecifier spec("RadarService/RadarProxy");
    auto proxy = RadarServiceProxy::Create(spec).value();

    // 等待服务可用
    proxy.WaitForService(ara::core::Timeout::FromSeconds(5));

    // 调用方法
    DetectionRequest req;
    req.range = 200.0;
    auto future = proxy.Detect(req);
    auto resp = future.get();
    if (resp.valid) {
        // 处理响应
    }

    // 订阅事件
    proxy.TargetList.Subscribe(
        [](const TargetArray& targets) {
            // 处理目标列表
        });
}

关键机制说明

上述代码展示了ara::com的核心交互模式:服务端通过继承生成的Skeleton类并重写方法实现业务逻辑,调用OfferService()将服务注册到通信中间件;客户端通过生成的Proxy类创建代理,使用WaitForService()等待服务发现完成,随后即可同步/异步调用方法或订阅事件。事件发送由服务端主动调用Send()触发,客户端通过Subscribe()注册回调接收。

SVG:服务发现与调用时序

客户端Proxy 通信中间件 服务端Skeleton OfferService() 1. 注册服务 服务发现响应 2. 发现服务 Detect(req) 3. 远程调用 返回Response 4. 响应返回 Subscribe(callback) 5. 订阅事件 Send(TargetList) 6. 事件推送

构建与运行

# 假设已安装AUTOSAR Adaptive基础库及代码生成器
# 1. 从ARXML生成代码
generator --input RadarService.arxml --output generated/

# 2. 编译服务端
g++ -std=c++17 -I generated/ -I /usr/include/ara \
    server.cpp generated/RadarService_skeleton.cpp \
    -lara_com -o radar_server

# 3. 编译客户端
g++ -std=c++17 -I generated/ -I /usr/include/ara \
    client.cpp generated/RadarService_proxy.cpp \
    -lara_com -o radar_client

# 4. 运行(需先启动通信中间件守护进程)
./radar_server &
./radar_client

验证方法与判定标准

验证步骤:

  1. 启动服务端后,观察日志出现Service offered,表明服务已注册到中间件;
  2. 运行客户端,若WaitForService在5秒内返回成功,说明服务发现正常;
  3. 客户端调用Detect方法后,若收到valid=true且target_count=3的响应,则方法调用链路通过;
  4. 服务端调用SendTargets()后,客户端订阅回调被触发并收到包含2个目标的TargetArray,则事件通信通过。

判定标准:以上4个步骤全部符合预期行为,即判定本案例实现正确。若服务发现超时或调用无响应,需检查中间件配置及实例标识符是否匹配。