文章目录
- 一、模块概述
- 二、模块架构
-
- [2.1 目录结构](#2.1 目录结构)
- [2.2 核心组件](#2.2 核心组件)
- [2.3 车辆适配层(canbus_vehicle)](#2.3 车辆适配层(canbus_vehicle))
- 三、接口调用流程图
-
- [3.1 整体Canbus流程图](#3.1 整体Canbus流程图)
- [3.2 指令发送流程图](#3.2 指令发送流程图)
- [3.3 状态接收流程图](#3.3 状态接收流程图)
- 四、关键源码分析
-
- [4.1 主组件源码分析](#4.1 主组件源码分析)
-
- [4.1.1 CanbusComponent](#4.1.1 CanbusComponent)
- [4.1.2 AbstractVehicleController 抽象车辆控制器](#4.1.2 AbstractVehicleController 抽象车辆控制器)
- [4.1.3 MessageManager 消息管理器](#4.1.3 MessageManager 消息管理器)
- [4.2 车辆适配层源码分析(以吉利车型为例)](#4.2 车辆适配层源码分析(以吉利车型为例))
-
- [4.2.1 CH Controller (吉利车型控制器)](#4.2.1 CH Controller (吉利车型控制器))
- 五、消息接口定义
-
- [5.1 控制指令消息](#5.1 控制指令消息)
-
- [5.1.1 ControlCommand(控制命令)](#5.1.1 ControlCommand(控制命令))
- [5.2 底盘状态消息](#5.2 底盘状态消息)
-
- [5.2.1 Chassis(底盘状态)](#5.2.1 Chassis(底盘状态))
- [5.2.2 ChassisDetail(详细底盘状态)](#5.2.2 ChassisDetail(详细底盘状态))
- 六、配置文件说明
-
- [6.1 Canbus配置文件(canbus_conf.pb.txt)](#6.1 Canbus配置文件(canbus_conf.pb.txt))
- [6.2 车辆特定配置(ch_vehicle_conf.pb.txt)](#6.2 车辆特定配置(ch_vehicle_conf.pb.txt))
- 七、性能优化策略
-
- [7.1 实时性优化](#7.1 实时性优化)
-
- [7.1.1 高频消息优先级队列](#7.1.1 高频消息优先级队列)
- [7.1.2 批量消息发送](#7.1.2 批量消息发送)
- [7.2 可靠性优化](#7.2 可靠性优化)
-
- [7.2.1 消息校验机制](#7.2.1 消息校验机制)
- [7.2.2 故障检测与恢复](#7.2.2 故障检测与恢复)
- 八、测试与验证
-
- [8.1 单元测试](#8.1 单元测试)
-
- [8.1.1 转向控制测试](#8.1.1 转向控制测试)
- [8.1.2 安全检查测试](#8.1.2 安全检查测试)
- [8.2 集成测试](#8.2 集成测试)
-
- [8.2.1 端到端通信测试](#8.2.1 端到端通信测试)
- [8.3 硬件在环测试](#8.3 硬件在环测试)
-
- [8.3.1 CAN总线仿真测试](#8.3.1 CAN总线仿真测试)
- 九、总结
-
- [9.1 技术特点](#9.1 技术特点)
- [9.2 关键性能指标](#9.2 关键性能指标)
团队博客: 汽车电子社区
一、模块概述
Canbus模块是Apollo自动驾驶系统的"神经系统",负责与车辆底盘进行CAN总线通信。该模块实现了控制指令的发送、车辆状态的接收、底盘数据的解析与封装,是自动驾驶系统与物理车辆交互的关键桥梁。Canbus模块通过标准化的接口支持不同车型的底盘适配,确保控制指令能够准确、实时地传达给车辆执行机构。
二、模块架构
2.1 目录结构
modules/canbus/
├── canbus_component/ # CAN总线主组件
├── common/ # 通用组件和工具
├── proto/ # 消息定义
├── conf/ # 配置文件
├── dag/ # DAG配置
└── launch/ # 启动配置
2.2 核心组件
1. CanbusComponent - CAN总线主组件
2. MessageManager - 消息管理器
3. AbstractVehicleController - 抽象车辆控制器
4. VehicleFactory - 车辆工厂类
2.3 车辆适配层(canbus_vehicle)
modules/canbus_vehicle/
├── ch/ # 吉利车型适配
├── demo/ # 演示车型适配
├── mkz/ # 林肯MKZ车型适配
├── lexus/ # 雷克萨斯车型适配
└── ... # 其他车型适配
三、接口调用流程图
3.1 整体Canbus流程图
通信错误 数据错误 硬件错误 控制指令输入 指令验证 指令转换 CAN消息打包 CAN总线发送 CAN总线接收 消息解析 数据验证 状态更新 底盘状态发布 车辆参数配置 控制器初始化 通信参数设置 通信建立 错误检测 错误类型 重连机制 数据过滤 故障上报 安全停车
3.2 指令发送流程图
横向控制 纵向控制 制动控制 挡位控制 成功 失败 ControlCommand 指令解析 控制类型 转向指令处理 速度指令处理 制动指令处理 挡位指令处理 转向角度转换 加速度转换 制动力转换 挡位状态转换 限幅检查 CAN消息编码 优先级排序 发送队列 CAN总线发送 发送确认 发送结果 状态更新 重发机制 日志记录
3.3 状态接收流程图
车辆状态 传感器数据 故障信息 系统状态 是 否 是 否 CAN消息接收 消息ID识别 消息类型 底盘状态解析 传感器数据解析 故障信息解析 系统状态解析 车速信息提取 传感器值提取 故障码提取 系统参数提取 数据有效性检查 数据有效 状态更新 数据丢弃 底盘状态发布 错误计数 下级模块通知 错误阈值检查 超过阈值 故障上报 继续监控
四、关键源码分析
4.1 主组件源码分析
4.1.1 CanbusComponent
类定义与继承关系:
cpp
class CanbusComponent : public cyber::Component<> {
public:
CanbusComponent();
~CanbusComponent();
bool Init() override;
bool Proc() override;
private:
void OnControlCommand(
const std::shared_ptr<control::ControlCommand>& command);
void OnChassisDetail(const std::shared_ptr<ChassisDetail>& detail);
bool InitCanClient();
bool InitVehicleController();
bool InitMessageManager();
// CAN客户端
std::unique_ptr<::apollo::drivers::can::CanClient> can_client_;
// 车辆控制器
std::unique_ptr<AbstractVehicleController> vehicle_controller_;
// 消息管理器
std::shared_ptr<MessageManager> message_manager_;
// 消息订阅器
std::shared_ptr<cyber::Reader<control::ControlCommand>> control_command_reader_;
// 消息发布器
std::shared_ptr<cyber::Writer<Chassis>> chassis_writer_;
std::shared_ptr<cyber::Writer<ChassisDetail>> chassis_detail_writer_;
std::shared_ptr<cyber::Writer<CheckResponse>> check_response_writer_;
// 配置参数
CanbusConf canbus_conf_;
bool is_initialized_ = false;
};
初始化过程:
cpp
bool CanbusComponent::Init() {
// 加载配置文件
if (!cyber::ComponentBase::GetProtoConfig(&canbus_conf_)) {
AERROR << "Unable to load canbus conf file: " << ConfigFilePath();
return false;
}
// 初始化CAN客户端
if (!InitCanClient()) {
AERROR << "Failed to init can client.";
return false;
}
// 初始化消息管理器
if (!InitMessageManager()) {
AERROR << "Failed to init message manager.";
return false;
}
// 初始化车辆控制器
if (!InitVehicleController()) {
AERROR << "Failed to init vehicle controller.";
return false;
}
// 创建控制指令订阅器
control_command_reader_ = node_->CreateReader<control::ControlCommand>(
canbus_conf_.control_command_topic(),
[this](const std::shared_ptr<control::ControlCommand>& command) {
OnControlCommand(command);
});
// 创建底盘状态发布器
chassis_writer_ = node_->CreateWriter<Chassis>(canbus_conf_.chassis_topic());
chassis_detail_writer_ = node_->CreateWriter<ChassisDetail>(
canbus_conf_.chassis_detail_topic());
check_response_writer_ = node_->CreateWriter<CheckResponse>(
canbus_conf_.check_response_topic());
is_initialized_ = true;
AINFO << "Canbus component initialized successfully.";
return true;
}
CAN客户端初始化:
cpp
bool CanbusComponent::InitCanClient() {
// 创建CAN客户端参数
apollo::drivers::can::CanClientParameter can_client_parameter;
// 设置CAN设备参数
can_client_parameter.set_brand(canbus_conf_.can_card_parameter().brand());
can_client_parameter.set_channel_id(canbus_conf_.can_card_parameter().channel_id());
can_client_parameter.set_type(canbus_conf_.can_card_parameter().type());
// 创建CAN客户端
can_client_ = std::unique_ptr<::apollo::drivers::can::CanClient>(
::apollo::drivers::can::CanClientFactory::Instance()->CreateCanClient(
can_client_parameter));
if (can_client_ == nullptr) {
AERROR << "Failed to create can client.";
return false;
}
// 初始化CAN客户端
if (!can_client_->Init()) {
AERROR << "Failed to init can client.";
return false;
}
// 启动CAN接收线程
if (!can_client_->Start()) {
AERROR << "Failed to start can client.";
return false;
}
AINFO << "Can client initialized successfully.";
return true;
}
车辆控制器初始化:
cpp
bool CanbusComponent::InitVehicleController() {
// 根据车型创建对应的控制器
vehicle_controller_ = VehicleFactory::Instance()->CreateObject(
canbus_conf_.vehicle_parameter().brand());
if (vehicle_controller_ == nullptr) {
AERROR << "Failed to create vehicle controller.";
return false;
}
// 初始化车辆控制器
if (!vehicle_controller_->Init(
canbus_conf_.vehicle_parameter(),
can_client_.get(),
message_manager_.get())) {
AERROR << "Failed to init vehicle controller.";
return false;
}
AINFO << "Vehicle controller initialized successfully.";
return true;
}
4.1.2 AbstractVehicleController 抽象车辆控制器
抽象基类定义:
cpp
class AbstractVehicleController {
public:
AbstractVehicleController() = default;
virtual ~AbstractVehicleController() = default;
// 初始化控制器
virtual bool Init(const VehicleParameter& params,
::apollo::drivers::can::CanClient* can_client,
MessageManager* message_manager) = 0;
// 启动控制器
virtual bool Start() = 0;
// 停止控制器
virtual void Stop() = 0;
// 更新控制指令
virtual void Update(ControlCommand* control_command) = 0;
// 获取底盘状态
virtual Chassis chassis() = 0;
// 获取详细底盘状态
virtual ChassisDetail chassis_detail() = 0;
protected:
VehicleParameter vehicle_params_;
::apollo::drivers::can::CanClient* can_client_ = nullptr;
MessageManager* message_manager_ = nullptr;
bool is_running_ = false;
};
4.1.3 MessageManager 消息管理器
消息管理器实现:
cpp
class MessageManager {
public:
MessageManager() = default;
virtual ~MessageManager() = default;
// 注册消息处理器
void RegisterRecvHandler(uint32_t message_id,
std::shared_ptr<ReceiveMessage> handler) {
recv_handlers_[message_id] = handler;
}
void RegisterSendHandler(uint32_t message_id,
std::shared_ptr<SendMessage> handler) {
send_handlers_[message_id] = handler;
}
// 处理接收到的CAN消息
void Parse(const CanFrame& frame) {
auto it = recv_handlers_.find(frame.can_id);
if (it != recv_handlers_.end()) {
it->second->Parse(frame.data, frame.len);
}
}
// 获取发送消息
bool GetSendMessages(std::vector<CanFrame>* frames) {
for (const auto& handler_pair : send_handlers_) {
CanFrame frame;
if (handler_pair.second->GetCanFrame(&frame)) {
frames->push_back(frame);
}
}
return !frames->empty();
}
private:
std::unordered_map<uint32_t, std::shared_ptr<ReceiveMessage>> recv_handlers_;
std::unordered_map<uint32_t, std::shared_ptr<SendMessage>> send_handlers_;
};
4.2 车辆适配层源码分析(以吉利车型为例)
4.2.1 CH Controller (吉利车型控制器)
控制器类定义:
cpp
class ChController : public AbstractVehicleController {
public:
ChController() = default;
virtual ~ChController() = default;
bool Init(const VehicleParameter& params,
::apollo::drivers::can::CanClient* can_client,
MessageManager* message_manager) override;
bool Start() override;
void Stop() override;
void Update(ControlCommand* control_command) override;
Chassis chassis() override;
ChassisDetail chassis_detail() override;
private:
// 控制指令处理
void SteeringControl(const control::ControlCommand& command);
void SpeedControl(const control::ControlCommand& command);
void BrakeControl(const control::ControlCommand& command);
void GearControl(const control::ControlCommand& command);
// 状态检查
bool CheckSafety(const ControlCommand& command);
bool CheckResponse();
private:
// 底盘状态
Chassis chassis_;
ChassisDetail chassis_detail_;
// 消息处理器
std::shared_ptr<ChSteeringCommand> steering_command_;
std::shared_ptr<ChSpeedCommand> speed_command_;
std::shared_ptr<ChBrakeCommand> brake_command_;
std::shared_ptr<ChGearCommand> gear_command_;
// 状态消息
std::shared_ptr<ChStatus> chassis_status_;
std::shared_ptr<ChWheelSpeed> wheel_speed_;
std::shared_ptr<ChBatteryInfo> battery_info_;
// 安全检查参数
double max_steering_angle_ = 0.0;
double max_acceleration_ = 0.0;
double max_deceleration_ = 0.0;
int64_t last_control_command_time_ = 0;
static constexpr int64_t CONTROL_COMMAND_TIMEOUT_MS = 100;
};
转向控制实现:
cpp
void ChController::SteeringControl(const control::ControlCommand& command) {
if (!steering_command_) {
return;
}
// 获取转向角度命令
double steering_angle = command.steering_target();
// 转向角度限制
steering_angle = std::max(-max_steering_angle_,
std::min(max_steering_angle_, steering_angle));
// 转向角度转换为电机位置
double motor_position = SteeringAngleToMotorPosition(steering_angle);
// 设置转向命令
steering_command_->set_steering_motor_target(motor_position);
steering_command_->set_steering_enable(true);
steering_command_->set_steering_clear(false);
steering_command_->set_checksum(SteeringCommandCheckSum(*steering_command_));
ADEBUG << "Steering control: angle=" << steering_angle
<< ", motor_position=" << motor_position;
}
速度控制实现:
cpp
void ChController::SpeedControl(const control::ControlCommand& command) {
if (!speed_command_) {
return;
}
// 获取速度和加速度命令
double speed_target = command.speed_target();
double acceleration = command.acceleration();
// 速度限制检查
double max_speed = vehicle_params_.max_speed();
speed_target = std::max(0.0, std::min(max_speed, speed_target));
// 加速度限制检查
acceleration = std::max(-max_deceleration_,
std::min(max_acceleration_, acceleration));
// 计算驱动力矩
double driving_torque = SpeedToDrivingTorque(speed_target, acceleration);
// 设置速度命令
speed_command_->set_speed_target(speed_target);
speed_command_->set_acceleration_target(acceleration);
speed_command_->set_driving_torque(driving_torque);
speed_command_->set_speed_enable(true);
speed_command_->set_speed_clear(false);
speed_command_->set_checksum(SpeedCommandCheckSum(*speed_command_));
ADEBUG << "Speed control: target=" << speed_target
<< ", acceleration=" << acceleration
<< ", torque=" << driving_torque;
}
安全检查实现:
cpp
bool ChController::CheckSafety(const ControlCommand& command) {
// 检查控制命令时效性
int64_t current_time = ::apollo::cyber::Time::Now().ToMillisecond();
if (current_time - last_control_command_time_ > CONTROL_COMMAND_TIMEOUT_MS) {
AERROR << "Control command timeout!";
return false;
}
// 检查驾驶模式
if (chassis_.driving_mode() != Chassis::COMPLETE_AUTO_DRIVE &&
chassis_.driving_mode() != Chassis::COMPLETE_MANUAL) {
AERROR << "Vehicle driving mode error!";
return false;
}
// 检查转向角度合理性
if (std::abs(command.steering_target()) > max_steering_angle_) {
AERROR << "Steering angle out of range: " << command.steering_target();
return false;
}
// 检查速度合理性
if (command.speed_target() < 0 || command.speed_target() > vehicle_params_.max_speed()) {
AERROR << "Speed out of range: " << command.speed_target();
return false;
}
// 检查车辆故障状态
if (chassis_.has_chassis_error()) {
AERROR << "Vehicle chassis error detected!";
return false;
}
return true;
}
状态更新实现:
cpp
void ChController::Update(ControlCommand* control_command) {
if (!is_running_ || !CheckSafety(*control_command)) {
AERROR << "Controller not running or safety check failed!";
return;
}
// 更新控制命令时间戳
last_control_command_time_ = ::apollo::cyber::Time::Now().ToMillisecond();
// 执行控制指令
SteeringControl(*control_command);
SpeedControl(*control_command);
BrakeControl(*control_command);
GearControl(*control_command);
// 发送CAN消息
std::vector<CanFrame> frames;
if (message_manager_->GetSendMessages(&frames)) {
for (const auto& frame : frames) {
can_client_->SendSingleFrame(frame);
}
}
// 更新底盘状态
UpdateChassisStatus();
}
void ChController::UpdateChassisStatus() {
if (!chassis_status_) {
return;
}
// 更新基础底盘信息
chassis_.set_driving_mode(chassis_status_->driving_mode());
chassis_.set_engine_started(chassis_status_->engine_started());
chassis_.set_speed_mps(chassis_status_->vehicle_speed());
chassis_.set_throttle_percentage(chassis_status_->throttle_percentage());
chassis_.set_brake_percentage(chassis_status_->brake_percentage());
chassis_.set_steering_percentage(chassis_status_->steering_angle() /
max_steering_angle_ * 100.0);
chassis_.set_gear_location(chassis_status_->gear_position());
chassis_.set_parking_brake(chassis_status_->parking_brake_status());
// 更新错误码
chassis_.set_chassis_error_code(chassis_status_->error_code());
// 更新详细状态
chassis_detail_.mutable_ch()->CopyFrom(*chassis_status_);
if (wheel_speed_) {
chassis_detail_.mutable_basic()->mutable_wheel_speed()->CopyFrom(*wheel_speed_);
}
if (battery_info_) {
chassis_detail_.mutable_ch()->mutable_battery_info()->CopyFrom(*battery_info_);
}
}
五、消息接口定义
5.1 控制指令消息
5.1.1 ControlCommand(控制命令)
protobuf
message ControlCommand {
// 控制头信息
apollo.common.Header header = 1;
// 转向控制
// 转向目标角度(弧度),左正右负
optional double steering_target = 2;
// 转向控制隔离
optional bool steering_isolated = 3;
// 速度控制
// 速度目标值(米/秒)
optional double speed_target = 4;
// 加速度目标值(米/秒²)
optional double acceleration = 5;
// 制动控制
// 制动百分比(0-100%)
optional double brake_percentage = 6;
// 制动控制隔离
optional bool brake_isolated = 7;
// 油门控制
// 油门百分比(0-100%)
optional double throttle_percentage = 8;
// 油门控制隔离
optional bool throttle_isolated = 9;
// 挡位控制
optional GearPosition gear_location = 10;
// 驻车制动
optional bool parking_brake = 11;
// 前灯控制
optional bool high_beam = 12;
optional bool low_beam = 13;
// 转向灯控制
optional bool left_turn = 14;
optional bool right_turn = 15;
// 雨刮控制
optional bool wiper = 16;
optional bool wiper_level = 17;
// 驾驶模式
optional DrivingMode driving_mode = 18;
}
enum GearPosition {
GEAR_NEUTRAL = 0;
GEAR_DRIVE = 1;
GEAR_REVERSE = 2;
GEAR_PARKING = 3;
GEAR_LOW = 4;
GEAR_INVALID = 5;
GEAR_NONE = 6;
}
enum DrivingMode {
COMPLETE_MANUAL = 0; // 完全手动
COMPLETE_AUTO_DRIVE = 1; // 完全自动驾驶
AUTO_STEER_ONLY = 2; // 仅自动转向
AUTO_SPEED_ONLY = 3; // 仅自动速度
}
enum ErrorCode {
NO_ERROR = 0;
CMD_MAY_lost = 1;
CONTROL_COMMUNICATION_ERROR = 2;
CHASSIS_ERROR = 3;
BYPASS_ERROR = 4;
}
5.2 底盘状态消息
5.2.1 Chassis(底盘状态)
protobuf
message Chassis {
// 底盘状态头信息
apollo.common.Header header = 1;
// 驾驶模式
optional DrivingMode driving_mode = 2;
// 错误码
optional ErrorCode chassis_error_code = 3;
// 发动机状态
optional bool engine_started = 4;
// 速度信息(米/秒)
optional double speed_mps = 5;
// 转向信息(百分比,左正右负)
optional double steering_percentage = 6;
// 油门信息(百分比)
optional double throttle_percentage = 7;
// 制动信息(百分比)
optional double brake_percentage = 8;
// 挡位信息
optional GearPosition gear_location = 9;
// 驻车制动状态
optional bool parking_brake = 10;
// 灯光状态
optional bool high_beam = 11;
optional bool low_beam = 12;
optional bool left_turn = 13;
optional bool right_turn = 14;
// 雨刮状态
optional bool wiper = 15;
// 驾驶模式时间戳
optional double driving_mode_timestamp = 16;
// CAN接收计数器
optional uint32 canbus_receiver_counter = 17;
// 电池信息
optional double battery_percentage = 18;
}
5.2.2 ChassisDetail(详细底盘状态)
protobuf
message ChassisDetail {
// 基础车辆信息
optional BasicInfo basic = 1;
// 安全信息
optional Safety safety = 2;
// 车辆特定信息(根据不同车型扩展)
optional Ch ch = 3; // 吉利车型
optional Mkz mkz = 4; // 林肯MKZ
optional Lexus lexus = 5; // 雷克萨斯
// ... 其他车型
message BasicInfo {
// 轮速信息
optional WheelSpeed wheel_speed = 1;
// 车身姿态
optional Body body = 2;
// GPS信息
optional Gps gps = 3;
}
message WheelSpeed {
optional double front_left = 1;
optional double front_right = 2;
optional double rear_left = 3;
optional double rear_right = 4;
}
message Body {
optional double roll_rate = 1;
optional double pitch_rate = 2;
optional double yaw_rate = 3;
optional double accel_longitudinal = 4;
optional double accel_lateral = 5;
optional double accel_vertical = 6;
}
}
六、配置文件说明
6.1 Canbus配置文件(canbus_conf.pb.txt)
protobuf
# CAN卡参数
can_card_parameter {
brand: ESD
type: PCI_CARD
channel_id: CHANNEL_ID_ZERO
num_ports: 4
}
# 车辆参数
vehicle_parameter {
brand: CH
max_steer_angle: 470.0 # 最大转向角度(度)
max_steer_angle_speed: 300.0 # 最大转向速度(度/秒)
min_steer_angle: -470.0 # 最小转向角度(度)
max_acceleration: 2.0 # 最大加速度(米/秒²)
max_deceleration: 6.0 # 最大减速度(米/秒²)
max_speed: 55.55 # 最大速度(米/秒)
min_speed: 0.0 # 最小速度(米/秒)
steer_ratio: 16.0 # 转向传动比
wheel_base: 2.844 # 轴距(米)
wheel_rolling_radius: 0.335 # 车轮滚动半径(米)
mass_fl: 800.0 # 前左轮质量(千克)
mass_fr: 800.0 # 前右轮质量(千克)
mass_rl: 800.0 # 后左轮质量(千克)
mass_rr: 800.0 # 后右轮质量(千克)
height_of_cog: 0.9 # 质心高度(米)
motor_torque_max: 1000.0 # 电机最大扭矩(牛·米)
}
# 话题配置
enable_debug_mode: true
control_command_topic: "/apollo/control"
chassis_topic: "/apollo/canbus/chassis"
chassis_detail_topic: "/apollo/canbus/chassis_detail"
check_response_topic: "/apollo/canbus/check_response"
6.2 车辆特定配置(ch_vehicle_conf.pb.txt)
protobuf
# 发送消息配置
send_id {
id: 0x111
period_ms: 20
description: "STEERING_CMD"
}
send_id {
id: 0x112
period_ms: 20
description: "SPEED_CMD"
}
send_id {
id: 0x113
period_ms: 20
description: "BRAKE_CMD"
}
send_id {
id: 0x114
period_ms: 20
description: "GEAR_CMD"
}
# 接收消息配置
receive_id {
id: 0x211
description: "CHASSIS_STATUS"
}
receive_id {
id: 0x212
description: "WHEEL_SPEED"
}
receive_id {
id: 0x213
description: "BATTERY_INFO"
}
七、性能优化策略
7.1 实时性优化
7.1.1 高频消息优先级队列
cpp
class PriorityMessageQueue {
public:
struct MessageItem {
CanFrame frame;
int priority;
uint64_t timestamp;
bool operator<(const MessageItem& other) const {
// 优先级高的先发送,时间戳小的先发送
return priority < other.priority ||
(priority == other.priority && timestamp > other.timestamp);
}
};
void Push(const CanFrame& frame, int priority) {
std::lock_guard<std::mutex> lock(mutex_);
queue_.push({frame, priority, Clock::NowInMillis()});
}
bool Pop(CanFrame* frame) {
std::lock_guard<std::mutex> lock(mutex_);
if (queue_.empty()) {
return false;
}
*frame = queue_.top().frame;
queue_.pop();
return true;
}
private:
std::priority_queue<MessageItem> queue_;
std::mutex mutex_;
};
7.1.2 批量消息发送
cpp
class BatchMessageSender {
public:
void SendBatchMessages() {
std::vector<CanFrame> frames;
// 收集所有待发送消息
if (message_manager_->GetSendMessages(&frames)) {
// 按优先级排序
std::sort(frames.begin(), frames.end(),
[](const CanFrame& a, const CanFrame& b) {
return GetMessagePriority(a.can_id) > GetMessagePriority(b.can_id);
});
// 批量发送
if (!frames.empty()) {
can_client_->SendBatch(frames);
}
}
}
private:
int GetMessagePriority(uint32_t can_id) {
// 根据CAN ID返回优先级
switch (can_id) {
case STEERING_CMD_ID: return 10; // 最高优先级
case BRAKE_CMD_ID: return 9; // 高优先级
case SPEED_CMD_ID: return 8; // 中高优先级
case GEAR_CMD_ID: return 7; // 中优先级
default: return 1; // 默认优先级
}
}
};
7.2 可靠性优化
7.2.1 消息校验机制
cpp
class MessageValidator {
public:
bool ValidateSteeringCommand(const ChSteeringCommand& command) {
// 校验和检查
uint8_t calculated_checksum = CalculateSteeringChecksum(command);
if (command.checksum() != calculated_checksum) {
AERROR << "Steering command checksum error!";
return false;
}
// 范围检查
if (std::abs(command.steering_motor_target()) > max_motor_position_) {
AERROR << "Steering motor position out of range!";
return false;
}
// 有效性检查
if (!command.steering_enable() && !command.steering_clear()) {
AERROR << "Invalid steering command state!";
return false;
}
return true;
}
bool ValidateSpeedCommand(const ChSpeedCommand& command) {
// 速度范围检查
if (command.speed_target() < 0 || command.speed_target() > max_speed_) {
AERROR << "Speed target out of range!";
return false;
}
// 加速度范围检查
if (std::abs(command.acceleration_target()) > max_acceleration_) {
AERROR << "Acceleration target out of range!";
return false;
}
return true;
}
private:
double max_motor_position_ = 5000.0;
double max_speed_ = 55.55;
double max_acceleration_ = 6.0;
};
7.2.2 故障检测与恢复
cpp
class FaultManager {
public:
enum FaultType {
COMMUNICATION_LOST = 0,
MESSAGE_TIMEOUT = 1,
DATA_OUT_OF_RANGE = 2,
CHECKSUM_ERROR = 3,
HARDWARE_FAILURE = 4
};
struct FaultInfo {
FaultType type;
uint64_t timestamp;
int count;
std::string description;
};
void ReportFault(FaultType type, const std::string& description) {
std::lock_guard<std::mutex> lock(mutex_);
uint64_t current_time = Clock::NowInMillis();
auto& fault = fault_map_[type];
fault.type = type;
fault.timestamp = current_time;
fault.count++;
fault.description = description;
AERROR << "Fault reported: " << description
<< " (type=" << type << ", count=" << fault.count << ")";
// 触发故障处理
HandleFault(fault);
}
void ClearFault(FaultType type) {
std::lock_guard<std::mutex> lock(mutex_);
fault_map_.erase(type);
AINFO << "Fault cleared: type=" << type;
}
private:
void HandleFault(const FaultInfo& fault) {
switch (fault.type) {
case COMMUNICATION_LOST:
if (fault.count > 5) {
TriggerSafeStop();
}
break;
case MESSAGE_TIMEOUT:
if (fault.count > 10) {
ReinitializeCanBus();
}
break;
case DATA_OUT_OF_RANGE:
// 记录但不立即处理,可能是暂时的数据异常
break;
case HARDWARE_FAILURE:
TriggerEmergencyStop();
break;
}
}
void TriggerSafeStop() {
AERROR << "Triggering safe stop due to persistent faults!";
// 发送安全停车指令
SendSafeStopCommand();
}
void TriggerEmergencyStop() {
AERROR << "Triggering emergency stop due to hardware failure!";
// 触发紧急制动
SendEmergencyBrakeCommand();
}
std::unordered_map<FaultType, FaultInfo> fault_map_;
std::mutex mutex_;
};
八、测试与验证
8.1 单元测试
8.1.1 转向控制测试
cpp
TEST(ChControllerTest, SteeringControl) {
ChController controller;
// 初始化控制器
EXPECT_TRUE(controller.Init(vehicle_params_, can_client_.get(),
message_manager_.get()));
EXPECT_TRUE(controller.Start());
// 创建控制命令
ControlCommand command;
command.set_steering_target(0.5); // 0.5弧度
// 执行控制
controller.Update(&command);
// 验证转向命令
auto steering_cmd = message_manager_->GetSendMessage<ChSteeringCommand>();
ASSERT_NE(steering_cmd, nullptr);
EXPECT_TRUE(steering_cmd->steering_enable());
EXPECT_GT(steering_cmd->steering_motor_target(), 0);
controller.Stop();
}
8.1.2 安全检查测试
cpp
TEST(ChControllerTest, SafetyCheck) {
ChController controller;
controller.Init(vehicle_params_, can_client_.get(), message_manager_.get());
// 正常控制命令
ControlCommand normal_command;
normal_command.set_steering_target(0.1);
normal_command.set_speed_target(10.0);
EXPECT_TRUE(controller.CheckSafety(normal_command));
// 超出转向范围
ControlCommand invalid_steering;
invalid_steering.set_steering_target(10.0); // 超出范围
EXPECT_FALSE(controller.CheckSafety(invalid_steering));
// 超出速度范围
ControlCommand invalid_speed;
invalid_speed.set_speed_target(100.0); // 超出范围
EXPECT_FALSE(controller.CheckSafety(invalid_speed));
}
8.2 集成测试
8.2.1 端到端通信测试
cpp
TEST(CanbusComponentTest, EndToEndCommunication) {
CanbusComponent component;
// 初始化组件
EXPECT_TRUE(component.Init());
// 发送控制命令
auto control_command = std::make_shared<ControlCommand>();
control_command->set_steering_target(0.1);
control_command->set_speed_target(5.0);
// 模拟消息接收
component.OnControlCommand(control_command);
// 等待处理完成
std::this_thread::sleep_for(std::chrono::milliseconds(50));
// 验证底盘状态发布
// 这里需要mock chassis_writer_来验证发布的内容
}
8.3 硬件在环测试
8.3.1 CAN总线仿真测试
cpp
class CanBusSimulator {
public:
void StartSimulation() {
simulation_thread_ = std::thread([this]() {
while (running_) {
// 模拟底盘状态消息
CanFrame status_frame;
status_frame.can_id = CHASSIS_STATUS_ID;
status_frame.len = 8;
GenerateChassisStatus(status_frame.data);
// 发送到CAN总线
can_client_->ReceiveSingleFrame(&status_frame);
std::this_thread::sleep_for(std::chrono::milliseconds(20));
}
});
}
void StopSimulation() {
running_ = false;
if (simulation_thread_.joinable()) {
simulation_thread_.join();
}
}
private:
void GenerateChassisStatus(uint8_t* data) {
// 模拟车速
static double speed = 0.0;
speed += (rand() % 100 - 50) * 0.01;
speed = std::max(0.0, std::min(30.0, speed));
// 填充数据
data[0] = static_cast<uint8_t>(speed * 100); // 速度(cm/s)
data[1] = static_cast<uint8_t>((static_cast<int>(speed * 100) >> 8));
// 其他状态数据...
}
bool running_ = true;
std::thread simulation_thread_;
::apollo::drivers::can::CanClient* can_client_;
};
九、总结
Canbus模块是Apollo自动驾驶系统与物理车辆交互的核心桥梁,通过标准化的接口和灵活的适配层设计,实现了与多种车型的兼容。
9.1 技术特点
1. 标准化接口 - 通过抽象基类和工厂模式实现车型无关的接口
2. 实时通信 - 基于CAN总线的高频、低延迟数据传输
3. 安全机制 - 多层安全检查和故障处理确保行车安全
4. 灵活适配 - 插件式架构支持不同车型的快速集成
5. 可靠性保障 - 完善的错误检测和恢复机制
9.2 关键性能指标
- 通信延迟 : < 5ms(控制指令到底盘)
- 更新频率 : 50-100Hz(根据车型配置)
- 消息可靠性 : > 99.9%(带重传机制)
- 故障检测时间 : < 100ms
- 内存占用 : < 100MB
- CPU占用率: < 5%
Canbus模块的高可靠性和实时性为自动驾驶系统的安全运行提供了坚实的通信保障,是整个自动驾驶系统不可或缺的基础组件。