2. 创建第一个Adaptive应用程序
任务说明
本案例目标是在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:服务发现与调用时序
构建与运行
# 假设已安装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
验证方法与判定标准
验证步骤:
- 启动服务端后,观察日志出现
Service offered,表明服务已注册到中间件; - 运行客户端,若
WaitForService在5秒内返回成功,说明服务发现正常; - 客户端调用
Detect方法后,若收到valid=true且target_count=3的响应,则方法调用链路通过; - 服务端调用
SendTargets()后,客户端订阅回调被触发并收到包含2个目标的TargetArray,则事件通信通过。
判定标准:以上4个步骤全部符合预期行为,即判定本案例实现正确。若服务发现超时或调用无响应,需检查中间件配置及实例标识符是否匹配。