2. 服务接口定义与部署
任务说明
本案例目标是在AUTOSAR Adaptive Platform(AP)环境中,为一个名为VehicleSpeed的服务定义包含方法(Method)和事件(Event)的接口,并将该服务接口部署到服务进程中。最终交付物为:ara::com服务接口定义(C++头文件)、服务实现骨架、服务部署清单(JSON),以及对应的构建与运行验证方式。
1. 服务接口定义
服务接口采用AUTOSAR AP的C++绑定(ara::com)。定义两个方法:GetSpeed(获取当前车速)和SetSpeedSource(设置速度来源),以及一个事件SpeedUpdate(周期性发布车速更新)。
// vehicle_speed_service_interface.hpp
#ifndef VEHICLE_SPEED_SERVICE_INTERFACE_HPP_
#define VEHICLE_SPEED_SERVICE_INTERFACE_HPP_
#include <cstdint>
#include <string>
#include "ara/com/types.h"
namespace ara {
namespace com {
// 方法:获取当前车速
class GetSpeed {
public:
struct Output {
std::uint32_t speed_kph; // 车速,单位 km/h
};
using Input = ara::com::Empty;
};
// 方法:设置速度来源
class SetSpeedSource {
public:
struct Input {
std::string source; // 来源标识,如 "CAN" / "SIM"
};
struct Output {
bool success; // 是否设置成功
};
};
// 事件:车速更新
class SpeedUpdate {
public:
struct SampleType {
std::uint32_t speed_kph;
std::uint64_t timestamp_ms;
};
};
// 服务接口定义
class VehicleSpeedService {
public:
using GetSpeedMethod = ara::com::Method<GetSpeed::Output, GetSpeed::Input>;
using SetSpeedSourceMethod = ara::com::Method<SetSpeedSource::Output, SetSpeedSource::Input>;
using SpeedUpdateEvent = ara::com::Event<SpeedUpdate::SampleType>;
static constexpr char const* kServiceName = "VehicleSpeed";
};
} // namespace com
} // namespace ara
#endif // VEHICLE_SPEED_SERVICE_INTERFACE_HPP_
2. 服务实现骨架
以下代码实现服务进程中的核心逻辑:维护当前车速值,提供方法处理,并周期性触发事件更新。为保持最小可复现,使用一个简单线程模拟速度源。
// vehicle_speed_service_impl.cpp
#include <thread>
#include <chrono>
#include <atomic>
#include <iostream>
#include "vehicle_speed_service_interface.hpp"
using namespace ara::com;
class VehicleSpeedServiceImpl {
public:
VehicleSpeedServiceImpl()
: current_speed_(0), running_(true) {}
void Init() {
// 注册方法处理
get_speed_handler_ = [this](const GetSpeed::Input& in, GetSpeed::Output& out) {
(void)in;
out.speed_kph = current_speed_.load();
};
set_source_handler_ = [this](const SetSpeedSource::Input& in, SetSpeedSource::Output& out) {
if (in.source == "CAN" || in.source == "SIM") {
source_ = in.source;
out.success = true;
} else {
out.success = false;
}
};
// 启动事件发布线程
event_thread_ = std::thread([this]() {
while (running_) {
std::this_thread::sleep_for(std::chrono::milliseconds(100));
if (source_ == "SIM") {
current_speed_ += 1; // 模拟速度递增
}
SpeedUpdate::SampleType sample;
sample.speed_kph = current_speed_.load();
sample.timestamp_ms = std::chrono::duration_cast<std::chrono::milliseconds>(
std::chrono::system_clock::now().time_since_epoch()).count();
// 实际部署时通过 proxy 或 skeleton 发布事件
// 此处仅演示数据生成逻辑
last_sample_ = sample;
}
});
}
void Stop() {
running_ = false;
if (event_thread_.joinable()) {
event_thread_.join();
}
}
// 供验证使用:获取最近一次事件样本
SpeedUpdate::SampleType GetLastSample() const { return last_sample_; }
private:
std::atomic<std::uint32_t> current_speed_;
std::atomic<bool> running_;
std::string source_ = "SIM";
std::thread event_thread_;
SpeedUpdate::SampleType last_sample_;
std::function<void(const GetSpeed::Input&, GetSpeed::Output&)> get_speed_handler_;
std::function<void(const SetSpeedSource::Input&, SetSpeedSource::Output&)> set_source_handler_;
};
// 主函数:演示服务生命周期
int main() {
VehicleSpeedServiceImpl service;
service.Init();
// 模拟调用 GetSpeed 方法
GetSpeed::Input in;
GetSpeed::Output out;
// 实际部署时通过 skeleton 的 dispatch 调用
// 此处直接调用内部逻辑验证
std::cout << "Service started. Press Enter to stop." << std::endl;
std::cin.get();
service.Stop();
return 0;
}
3. 服务部署清单
在AP中,服务部署通过JSON清单描述服务实例与进程的绑定关系。以下为最小部署配置:
{
"service_instances": [
{
"service_id": "VehicleSpeed",
"instance_id": 1,
"methods": [
{
"name": "GetSpeed",
"type": "method"
},
{
"name": "SetSpeedSource",
"type": "method"
}
],
"events": [
{
"name": "SpeedUpdate",
"type": "event"
}
],
"deployment": {
"process": "VehicleSpeedServiceProcess",
"communication": "someip",
"network": "eth0"
}
}
]
}
4. 构建与运行
依赖:AUTOSAR AP实现(如Adaptive AUTOSAR官方栈或商业实现)、C++14及以上编译器、CMake。构建命令:
g++ -std=c++14 -I./ vehicle_speed_service_impl.cpp -o vehicle_speed_service -lpthread
运行:
./vehicle_speed_service
5. 验证方法与判定标准
本案例代码为教学演示,未接入完整ara::com运行时。验证分为两层:
- 编译验证:上述命令应无错误编译通过,生成可执行文件。
- 逻辑验证:运行程序后,观察控制台输出“Service started”,程序保持运行;按Enter后正常退出。若接入真实AP运行时,可通过ara::com proxy调用
GetSpeed方法,返回值应等于当前模拟速度;订阅SpeedUpdate事件,应每100ms收到一次包含递增速度值的样本。
判定标准:编译无错误;程序能启动并响应Enter退出;若在完整AP环境中,方法调用返回有效速度值,事件订阅能周期性收到数据,即判定通过。