750 lines
22 KiB
C++
750 lines
22 KiB
C++
#pragma once
|
||
|
||
#include <linux/can.h>
|
||
|
||
#include <algorithm>
|
||
#include <cstdint>
|
||
#include <cstring>
|
||
#include <mutex>
|
||
#include <string>
|
||
#include <vector>
|
||
|
||
#include "utils.h"
|
||
|
||
// 整车数据
|
||
struct VehicleData
|
||
{
|
||
uint8_t vehicle_status; // 车辆状态
|
||
uint8_t charge_status; // 充电状态
|
||
uint8_t run_mode; // 运行模式
|
||
uint16_t speed; // 车速
|
||
uint32_t mileage; // 累计里程
|
||
uint16_t total_voltage; // 总电压
|
||
uint16_t total_current; // 总电流
|
||
uint8_t soc; // 电池SOC
|
||
uint8_t dc_dc_status; // DC-DC状态
|
||
uint8_t gear; // 档位
|
||
uint16_t insulation_resistance; // 绝缘电阻
|
||
uint8_t accel_pedal; // 油门踏板
|
||
uint8_t brake_pedal; // 制动踏板
|
||
|
||
VehicleData() { std::memset(this, 0xFF, sizeof(VehicleData)); }
|
||
|
||
// TLV 编码
|
||
std::vector<uint8_t> encode() const
|
||
{
|
||
std::vector<uint8_t> result;
|
||
|
||
// 类型固定为 0x01(整车数据)
|
||
result.push_back(0x01);
|
||
|
||
// 按字段顺序打包数据
|
||
result.push_back(vehicle_status);
|
||
result.push_back(charge_status);
|
||
result.push_back(run_mode);
|
||
|
||
result.push_back((speed >> 8) & 0xFF); // 高字节
|
||
result.push_back(speed & 0xFF); // 低字节
|
||
|
||
result.push_back((mileage >> 24) & 0xFF);
|
||
result.push_back((mileage >> 16) & 0xFF);
|
||
result.push_back((mileage >> 8) & 0xFF);
|
||
result.push_back(mileage & 0xFF);
|
||
|
||
result.push_back((total_voltage >> 8) & 0xFF);
|
||
result.push_back(total_voltage & 0xFF);
|
||
|
||
result.push_back((total_current >> 8) & 0xFF);
|
||
result.push_back(total_current & 0xFF);
|
||
|
||
result.push_back(soc);
|
||
result.push_back(dc_dc_status);
|
||
result.push_back(gear);
|
||
|
||
result.push_back((insulation_resistance >> 8) & 0xFF);
|
||
result.push_back(insulation_resistance & 0xFF);
|
||
|
||
result.push_back(accel_pedal);
|
||
result.push_back(brake_pedal);
|
||
|
||
return result;
|
||
}
|
||
};
|
||
|
||
// 电机数据
|
||
struct MotorData
|
||
{
|
||
uint8_t seq; // 驱动电机序号
|
||
uint8_t status; // 电机状态
|
||
uint8_t controller_temp; // 控制器温度
|
||
uint16_t speed; // 转速
|
||
uint16_t torque; // 转矩
|
||
uint8_t motor_temp; // 电机温度
|
||
uint16_t input_voltage; // 控制器输入电压
|
||
uint16_t dc_current; // 控制器直流母线电流
|
||
|
||
MotorData() { std::memset(this, 0xFF, sizeof(MotorData)); }
|
||
|
||
// 编码单个电机
|
||
std::vector<uint8_t> encode() const
|
||
{
|
||
std::vector<uint8_t> result;
|
||
result.push_back(seq);
|
||
result.push_back(status);
|
||
result.push_back(controller_temp);
|
||
result.push_back((speed >> 8) & 0xFF);
|
||
result.push_back(speed & 0xFF);
|
||
result.push_back((torque >> 8) & 0xFF);
|
||
result.push_back(torque & 0xFF);
|
||
result.push_back(motor_temp);
|
||
result.push_back((input_voltage >> 8) & 0xFF);
|
||
result.push_back(input_voltage & 0xFF);
|
||
result.push_back((dc_current >> 8) & 0xFF);
|
||
result.push_back(dc_current & 0xFF);
|
||
return result;
|
||
}
|
||
};
|
||
|
||
struct VehicleMotors
|
||
{
|
||
std::vector<MotorData> motors; // 驱动电机列表
|
||
|
||
VehicleMotors() { motors.resize(2); } // 默认支持 2 台电机
|
||
|
||
// 编码整个驱动电机信息体 (0x02)
|
||
std::vector<uint8_t> encode() const
|
||
{
|
||
std::vector<uint8_t> result;
|
||
result.push_back(0x02); // 类型标识
|
||
result.push_back(static_cast<uint8_t>(motors.size())); // 电机数量
|
||
|
||
for (const auto& m : motors)
|
||
{
|
||
auto motor_bytes = m.encode();
|
||
result.insert(result.end(), motor_bytes.begin(), motor_bytes.end());
|
||
}
|
||
return result;
|
||
}
|
||
};
|
||
|
||
// 车辆位置信息
|
||
struct VehiclePosition
|
||
{
|
||
uint8_t status; // 定位状态位
|
||
uint32_t longitude; // 经度 × 10^6
|
||
uint32_t latitude; // 纬度 × 10^6
|
||
uint16_t heading; // 方向 0~359, 精度0.1°
|
||
|
||
VehiclePosition() { std::memset(this, 0xFF, sizeof(VehiclePosition)); }
|
||
|
||
std::vector<uint8_t> encode() const
|
||
{
|
||
std::vector<uint8_t> result;
|
||
result.push_back(0x05); // 类型标识
|
||
result.push_back(status); // 状态字节
|
||
|
||
// 经度
|
||
result.push_back((longitude >> 24) & 0xFF);
|
||
result.push_back((longitude >> 16) & 0xFF);
|
||
result.push_back((longitude >> 8) & 0xFF);
|
||
result.push_back(longitude & 0xFF);
|
||
|
||
// 纬度
|
||
result.push_back((latitude >> 24) & 0xFF);
|
||
result.push_back((latitude >> 16) & 0xFF);
|
||
result.push_back((latitude >> 8) & 0xFF);
|
||
result.push_back(latitude & 0xFF);
|
||
|
||
// 方向
|
||
result.push_back((heading >> 8) & 0xFF);
|
||
result.push_back(heading & 0xFF);
|
||
|
||
return result;
|
||
}
|
||
};
|
||
|
||
// 极值数据
|
||
struct ExtremeData
|
||
{
|
||
uint8_t highest_voltage_subsys; // 最高电压子系统号
|
||
uint16_t highest_voltage_cell; // 最高电压单体代号
|
||
uint16_t highest_voltage_value; // 电池单体电压最高值
|
||
|
||
uint8_t lowest_voltage_subsys; // 最低电压子系统号
|
||
uint16_t lowest_voltage_cell; // 最低电压单体代号
|
||
uint16_t lowest_voltage_value; // 电池单体电压最低值
|
||
|
||
uint8_t highest_temp_subsys; // 最高温度子系统号
|
||
uint8_t highest_temp_probe; // 最高温度探针序号
|
||
uint8_t highest_temp_value; // 最高温度值
|
||
|
||
uint8_t lowest_temp_subsys; // 最低温度子系统号
|
||
uint8_t lowest_temp_probe; // 最低温度探针序号
|
||
uint8_t lowest_temp_value; // 最低温度值
|
||
|
||
ExtremeData() { std::memset(this, 0xFF, sizeof(ExtremeData)); }
|
||
|
||
std::vector<uint8_t> encode() const
|
||
{
|
||
std::vector<uint8_t> result;
|
||
result.push_back(0x06); // 类型标识
|
||
|
||
result.push_back(highest_voltage_subsys);
|
||
result.push_back((highest_voltage_cell >> 8) & 0xFF);
|
||
result.push_back(highest_voltage_cell & 0xFF);
|
||
result.push_back((highest_voltage_value >> 8) & 0xFF);
|
||
result.push_back(highest_voltage_value & 0xFF);
|
||
|
||
result.push_back(lowest_voltage_subsys);
|
||
result.push_back((lowest_voltage_cell >> 8) & 0xFF);
|
||
result.push_back(lowest_voltage_cell & 0xFF);
|
||
result.push_back((lowest_voltage_value >> 8) & 0xFF);
|
||
result.push_back(lowest_voltage_value & 0xFF);
|
||
|
||
result.push_back(highest_temp_subsys);
|
||
result.push_back(highest_temp_probe);
|
||
result.push_back(highest_temp_value);
|
||
|
||
result.push_back(lowest_temp_subsys);
|
||
result.push_back(lowest_temp_probe);
|
||
result.push_back(lowest_temp_value);
|
||
|
||
return result;
|
||
}
|
||
};
|
||
|
||
// 报警数据
|
||
struct AlarmData
|
||
{
|
||
uint8_t highest_level; // 最高报警等级
|
||
uint32_t common_flags; // 通用报警标志
|
||
|
||
uint8_t n1; // 可充电储能装置故障总数
|
||
std::vector<uint32_t> battery_fault_codes; // 电池故障代码列表 (4*N1)
|
||
|
||
uint8_t n2; // 驱动电机故障总数
|
||
std::vector<uint32_t> motor_fault_codes; // 驱动电机故障代码列表 (4*N2)
|
||
|
||
uint8_t n3; // 发动机故障总数
|
||
std::vector<uint32_t> engine_fault_codes; // 发动机故障代码列表 (4*N3)
|
||
|
||
uint8_t n4; // 其他故障总数
|
||
std::vector<uint32_t> other_fault_codes; // 其他故障代码列表 (4*N4)
|
||
|
||
uint8_t n5; // 普通故障总数
|
||
std::vector<uint32_t> normal_fault_codes; // 普通故障代码列表 (4*N5)
|
||
|
||
AlarmData() : highest_level(0xFF), common_flags(0xFFFFFFFF), n1(0), n2(0), n3(0), n4(0), n5(0)
|
||
{
|
||
// 清空所有 vector,防止残留旧数据
|
||
battery_fault_codes.clear();
|
||
motor_fault_codes.clear();
|
||
engine_fault_codes.clear();
|
||
other_fault_codes.clear();
|
||
normal_fault_codes.clear();
|
||
}
|
||
|
||
std::vector<uint8_t> encode() const
|
||
{
|
||
std::vector<uint8_t> result;
|
||
result.push_back(0x07); // 类型标识
|
||
|
||
result.push_back(highest_level);
|
||
|
||
// 通用报警标志(DWORD)
|
||
result.push_back((common_flags >> 24) & 0xFF);
|
||
result.push_back((common_flags >> 16) & 0xFF);
|
||
result.push_back((common_flags >> 8) & 0xFF);
|
||
result.push_back(common_flags & 0xFF);
|
||
|
||
// 电池故障
|
||
result.push_back(n1);
|
||
for (uint32_t code : battery_fault_codes)
|
||
{
|
||
result.push_back((code >> 24) & 0xFF);
|
||
result.push_back((code >> 16) & 0xFF);
|
||
result.push_back((code >> 8) & 0xFF);
|
||
result.push_back(code & 0xFF);
|
||
}
|
||
|
||
// 驱动电机故障
|
||
result.push_back(n2);
|
||
for (uint32_t code : motor_fault_codes)
|
||
{
|
||
result.push_back((code >> 24) & 0xFF);
|
||
result.push_back((code >> 16) & 0xFF);
|
||
result.push_back((code >> 8) & 0xFF);
|
||
result.push_back(code & 0xFF);
|
||
}
|
||
|
||
// 发动机故障
|
||
result.push_back(n3);
|
||
for (uint32_t code : engine_fault_codes)
|
||
{
|
||
result.push_back((code >> 24) & 0xFF);
|
||
result.push_back((code >> 16) & 0xFF);
|
||
result.push_back((code >> 8) & 0xFF);
|
||
result.push_back(code & 0xFF);
|
||
}
|
||
|
||
// 其他故障
|
||
result.push_back(n4);
|
||
for (uint32_t code : other_fault_codes)
|
||
{
|
||
result.push_back((code >> 24) & 0xFF);
|
||
result.push_back((code >> 16) & 0xFF);
|
||
result.push_back((code >> 8) & 0xFF);
|
||
result.push_back(code & 0xFF);
|
||
}
|
||
|
||
// 普通故障
|
||
result.push_back(n5);
|
||
for (uint32_t code : normal_fault_codes)
|
||
{
|
||
result.push_back((code >> 24) & 0xFF);
|
||
result.push_back((code >> 16) & 0xFF);
|
||
result.push_back((code >> 8) & 0xFF);
|
||
result.push_back(code & 0xFF);
|
||
}
|
||
|
||
return result;
|
||
}
|
||
};
|
||
|
||
// 故障池
|
||
struct FaultPool
|
||
{
|
||
struct FaultItem
|
||
{
|
||
uint32_t code; // 故障码(唯一)
|
||
uint8_t ecu; // 来自哪个 ECU
|
||
uint8_t level; // 故障等级
|
||
uint64_t last_seen_ts; // 上次收到该故障的时间
|
||
};
|
||
|
||
mutable std::mutex mutex;
|
||
std::vector<FaultItem> items;
|
||
|
||
// 新故障 or 刷新已有故障
|
||
void add_or_update(uint8_t ecu, uint8_t level, uint32_t code)
|
||
{
|
||
std::lock_guard<std::mutex> lock(mutex);
|
||
|
||
uint64_t now = common::get_timestamp_ms();
|
||
|
||
for (auto& f : items)
|
||
{
|
||
if (f.code == code && f.ecu == ecu)
|
||
{
|
||
f.level = level;
|
||
f.last_seen_ts = now;
|
||
return;
|
||
}
|
||
}
|
||
|
||
// 新故障
|
||
items.push_back({code, ecu, level, now});
|
||
}
|
||
|
||
// 超时自动清除故障(例如 500ms 未收到 → 故障消失)
|
||
void purge_timeout(uint64_t timeout_ms)
|
||
{
|
||
std::lock_guard<std::mutex> lock(mutex);
|
||
|
||
uint64_t now = common::get_timestamp_ms();
|
||
|
||
items.erase(std::remove_if(items.begin(), items.end(),
|
||
[&](const FaultItem& f) { return (now - f.last_seen_ts > timeout_ms); }),
|
||
items.end());
|
||
}
|
||
|
||
// 获取快照(线程安全)
|
||
std::vector<FaultItem> snapshot() const
|
||
{
|
||
std::lock_guard<std::mutex> lock(mutex);
|
||
return items; // 拷贝副本
|
||
}
|
||
};
|
||
|
||
// 可充电储能装置电压数据
|
||
struct BatteryUnit
|
||
{
|
||
uint16_t voltage; // 单体电池电压
|
||
|
||
BatteryUnit() : voltage(0xFFFF) {} // 默认无效
|
||
};
|
||
|
||
struct StorageSubsystem
|
||
{
|
||
uint8_t subsystem_id; // 可充电储能子系统号
|
||
uint16_t voltage; // 储能装置总电压
|
||
uint16_t current; // 储能装置总电流
|
||
uint16_t total_cells; // 单体电池总数
|
||
uint16_t start_cell_index; // 本帧起始电池序号
|
||
uint16_t frame_cells; // 本帧单体电池数量
|
||
std::vector<BatteryUnit> cells; // 单体电池电压列表
|
||
|
||
StorageSubsystem()
|
||
: subsystem_id(0xFF), voltage(0xFFFF), current(0xFFFF), total_cells(0), start_cell_index(0xFFFF), frame_cells(0)
|
||
{
|
||
cells.clear(); // 空容器,防止脏数据
|
||
}
|
||
|
||
std::vector<uint8_t> encode() const
|
||
{
|
||
std::vector<uint8_t> result;
|
||
result.push_back(subsystem_id);
|
||
result.push_back((voltage >> 8) & 0xFF);
|
||
result.push_back(voltage & 0xFF);
|
||
result.push_back((current >> 8) & 0xFF);
|
||
result.push_back(current & 0xFF);
|
||
result.push_back((total_cells >> 8) & 0xFF);
|
||
result.push_back(total_cells & 0xFF);
|
||
result.push_back((start_cell_index >> 8) & 0xFF);
|
||
result.push_back(start_cell_index & 0xFF);
|
||
result.push_back((frame_cells >> 8) & 0xFF);
|
||
result.push_back(frame_cells & 0xFF);
|
||
|
||
for (const auto& cell : cells)
|
||
{
|
||
result.push_back((cell.voltage >> 8) & 0xFF);
|
||
result.push_back(cell.voltage & 0xFF);
|
||
}
|
||
|
||
return result;
|
||
}
|
||
};
|
||
|
||
struct StorageVoltageData
|
||
{
|
||
static constexpr uint8_t kSubsystemCount = 1; // 现实世界:只有 1 个储能系统
|
||
|
||
uint8_t subsystem_count; // 对外上报给 GB32960 的字段
|
||
StorageSubsystem subsystem; // 唯一子系统
|
||
|
||
StorageVoltageData() : subsystem_count(kSubsystemCount)
|
||
{
|
||
// 协议现实:EV 默认 1
|
||
subsystem.subsystem_id = 1;
|
||
subsystem.start_cell_index = 1;
|
||
}
|
||
|
||
std::vector<uint8_t> encode() const
|
||
{
|
||
std::vector<uint8_t> result;
|
||
result.push_back(0x08); // 类型标识
|
||
result.push_back(subsystem_count);
|
||
|
||
auto sub_bytes = subsystem.encode();
|
||
result.insert(result.end(), sub_bytes.begin(), sub_bytes.end());
|
||
|
||
return result;
|
||
}
|
||
};
|
||
|
||
// 可充电储能装置温度数据
|
||
struct TemperatureProbe
|
||
{
|
||
uint8_t temp; // 温度值
|
||
|
||
TemperatureProbe() : temp(0xFF) {} // 默认无效
|
||
};
|
||
|
||
struct StorageTempSubsystem
|
||
{
|
||
uint8_t subsystem_id; // 可充电储能子系统号
|
||
uint16_t probe_count; // 温度探针个数
|
||
std::vector<TemperatureProbe> probes; // 探针列表
|
||
|
||
StorageTempSubsystem() : subsystem_id(0xFF), probe_count(0)
|
||
{
|
||
probes.clear(); // 空容器,防止脏数据
|
||
}
|
||
|
||
std::vector<uint8_t> encode() const
|
||
{
|
||
std::vector<uint8_t> result;
|
||
result.push_back(subsystem_id);
|
||
result.push_back((probe_count >> 8) & 0xFF);
|
||
result.push_back(probe_count & 0xFF);
|
||
|
||
for (const auto& p : probes) { result.push_back(p.temp); }
|
||
|
||
return result;
|
||
}
|
||
};
|
||
|
||
struct StorageTempData
|
||
{
|
||
static constexpr uint8_t kSubsystemCount = 1;
|
||
|
||
uint8_t subsystem_count; // 可充电储能子系统个数
|
||
StorageTempSubsystem subsystem; // 唯一子系统
|
||
|
||
StorageTempData() : subsystem_count(kSubsystemCount)
|
||
{
|
||
subsystem.subsystem_id = 1; // 与电压侧保持一致
|
||
}
|
||
|
||
std::vector<uint8_t> encode() const
|
||
{
|
||
std::vector<uint8_t> result;
|
||
result.push_back(0x09); // 类型标识
|
||
result.push_back(subsystem_count);
|
||
|
||
auto sub_bytes = subsystem.encode();
|
||
result.insert(result.end(), sub_bytes.begin(), sub_bytes.end());
|
||
|
||
return result;
|
||
}
|
||
};
|
||
|
||
// 驱动/制动数据
|
||
struct DriveBrakeData
|
||
{
|
||
uint16_t speed; // 车速
|
||
uint16_t reserved1; // 预留
|
||
uint16_t accel_opening; // 油门开度
|
||
uint16_t torque; // 扭矩
|
||
uint16_t brake_opening; // 制动踏板开度
|
||
uint16_t deceleration; // 减速度
|
||
uint8_t parking_status; // 驻车状态反馈
|
||
uint16_t wheel_speed1; // 轮速1
|
||
uint16_t wheel_speed2; // 轮速2
|
||
uint16_t wheel_speed3; // 轮速3
|
||
uint16_t wheel_speed4; // 轮速4
|
||
uint8_t reserved_status1; // 预留状态1
|
||
uint8_t reserved_status2; // 预留状态2
|
||
uint8_t reserved_status3; // 预留状态3
|
||
uint16_t reserved_status4; // 预留状态4
|
||
uint16_t reserved_status5; // 预留状态5
|
||
uint16_t reserved_status6; // 预留状态6
|
||
|
||
DriveBrakeData() { std::memset(this, 0xFF, sizeof(DriveBrakeData)); }
|
||
|
||
std::vector<uint8_t> encode() const
|
||
{
|
||
std::vector<uint8_t> result;
|
||
result.push_back(0x85); // 类型标识
|
||
|
||
auto pushWord = [&](uint16_t val)
|
||
{
|
||
result.push_back((val >> 8) & 0xFF);
|
||
result.push_back(val & 0xFF);
|
||
};
|
||
|
||
// 按顺序编码
|
||
pushWord(speed);
|
||
pushWord(reserved1);
|
||
pushWord(accel_opening);
|
||
pushWord(torque);
|
||
pushWord(brake_opening);
|
||
pushWord(deceleration);
|
||
result.push_back(parking_status);
|
||
pushWord(wheel_speed1);
|
||
pushWord(wheel_speed2);
|
||
pushWord(wheel_speed3);
|
||
pushWord(wheel_speed4);
|
||
result.push_back(reserved_status1);
|
||
result.push_back(reserved_status2);
|
||
result.push_back(reserved_status3);
|
||
pushWord(reserved_status4);
|
||
pushWord(reserved_status5);
|
||
pushWord(reserved_status6);
|
||
|
||
return result;
|
||
}
|
||
};
|
||
|
||
// 轮胎数据
|
||
struct TireInfo
|
||
{
|
||
uint8_t position; // 轮胎位置
|
||
uint16_t pressure; // 胎压
|
||
uint8_t temperature; // 胎温
|
||
uint16_t angle; // 转向角度
|
||
uint8_t warning; // 轮胎预警
|
||
uint8_t reserved1; // 预留状态1
|
||
uint8_t reserved2; // 预留状态2
|
||
uint16_t reserved3; // 预留状态3
|
||
uint16_t reserved4; // 预留状态4
|
||
|
||
TireInfo() { std::memset(this, 0xFF, sizeof(TireInfo)); }
|
||
|
||
std::vector<uint8_t> encode() const
|
||
{
|
||
std::vector<uint8_t> result;
|
||
result.push_back(position);
|
||
result.push_back((pressure >> 8) & 0xFF);
|
||
result.push_back(pressure & 0xFF);
|
||
result.push_back(temperature);
|
||
result.push_back((angle >> 8) & 0xFF);
|
||
result.push_back(angle & 0xFF);
|
||
result.push_back(warning);
|
||
result.push_back(reserved1);
|
||
result.push_back(reserved2);
|
||
result.push_back((reserved3 >> 8) & 0xFF);
|
||
result.push_back(reserved3 & 0xFF);
|
||
result.push_back((reserved4 >> 8) & 0xFF);
|
||
result.push_back(reserved4 & 0xFF);
|
||
return result;
|
||
}
|
||
};
|
||
|
||
struct TireData
|
||
{
|
||
uint8_t tire_count; // 轮胎数量
|
||
std::vector<TireInfo> tires; // 轮胎列表
|
||
|
||
TireData() : tire_count(0) { tires.clear(); }
|
||
|
||
std::vector<uint8_t> encode() const
|
||
{
|
||
std::vector<uint8_t> result;
|
||
result.push_back(0x86); // 类型标识
|
||
result.push_back(tire_count);
|
||
|
||
for (const auto& t : tires)
|
||
{
|
||
auto tire_bytes = t.encode();
|
||
result.insert(result.end(), tire_bytes.begin(), tire_bytes.end());
|
||
}
|
||
|
||
return result;
|
||
}
|
||
};
|
||
|
||
// 前域开关数据
|
||
struct FrontSwitchData
|
||
{
|
||
std::vector<uint8_t> switches; // 0x01 ~ 0x17 共 23 个参数
|
||
|
||
FrontSwitchData()
|
||
{
|
||
switches.resize(0x17, 0xFF); // 默认全部无效
|
||
}
|
||
|
||
void setParam(uint8_t id, uint8_t value)
|
||
{
|
||
if (id >= 1 && id <= 0x17) { switches[id - 1] = value; }
|
||
}
|
||
|
||
std::vector<uint8_t> encode() const
|
||
{
|
||
std::vector<uint8_t> result;
|
||
|
||
// 先统计有效参数
|
||
uint8_t count = 0;
|
||
for (auto v : switches)
|
||
if (v != 0xFF) ++count;
|
||
|
||
// 如果一个有效开关都没有
|
||
if (count == 0) return result;
|
||
|
||
result.reserve(2 + count * 2);
|
||
|
||
result.push_back(0x87); // 类型标识
|
||
result.push_back(count); // 实际参数个数
|
||
|
||
for (uint8_t id = 1; id <= 0x17; ++id)
|
||
{
|
||
uint8_t v = switches[id - 1];
|
||
if (v == 0xFF) continue;
|
||
|
||
result.push_back(id);
|
||
result.push_back(v);
|
||
}
|
||
|
||
return result;
|
||
}
|
||
};
|
||
|
||
// 整车数据补充
|
||
struct VehicleFullData
|
||
{
|
||
uint8_t control_mode; // 车辆控制模式
|
||
uint8_t emergency_btn; // 紧急按钮状态
|
||
uint16_t speed_limit; // 车辆限速
|
||
uint8_t lock_status; // 锁车状态
|
||
uint32_t total_charge; // 车辆累计充电量
|
||
uint8_t reserved1; // 预留状态1
|
||
uint8_t reserved2; // 预留状态2
|
||
uint8_t reserved3; // 预留状态3
|
||
uint16_t reserved4; // 预留状态4
|
||
uint16_t reserved5; // 预留状态5
|
||
uint16_t reserved6; // 预留状态6
|
||
|
||
VehicleFullData() { std::memset(this, 0xFF, sizeof(VehicleFullData)); }
|
||
|
||
std::vector<uint8_t> encode() const
|
||
{
|
||
std::vector<uint8_t> result;
|
||
result.push_back(0x88); // 类型标识
|
||
|
||
result.push_back(control_mode);
|
||
result.push_back(emergency_btn);
|
||
// WORD 高字节在前
|
||
result.push_back((speed_limit >> 8) & 0xFF);
|
||
result.push_back(speed_limit & 0xFF);
|
||
result.push_back(lock_status);
|
||
|
||
// DWORD 高字节在前
|
||
result.push_back((total_charge >> 24) & 0xFF);
|
||
result.push_back((total_charge >> 16) & 0xFF);
|
||
result.push_back((total_charge >> 8) & 0xFF);
|
||
result.push_back(total_charge & 0xFF);
|
||
|
||
result.push_back(reserved1);
|
||
result.push_back(reserved2);
|
||
result.push_back(reserved3);
|
||
result.push_back((reserved4 >> 8) & 0xFF);
|
||
result.push_back(reserved4 & 0xFF);
|
||
result.push_back((reserved5 >> 8) & 0xFF);
|
||
result.push_back(reserved5 & 0xFF);
|
||
result.push_back((reserved6 >> 8) & 0xFF);
|
||
result.push_back(reserved6 & 0xFF);
|
||
|
||
return result;
|
||
}
|
||
};
|
||
|
||
// 数据结构体定义
|
||
extern VehicleData current_vehicle_data;
|
||
extern std::mutex vehicle_data_mutex;
|
||
|
||
extern VehicleMotors current_vehicle_motors;
|
||
extern std::mutex vehicle_motors_mutex;
|
||
|
||
extern VehiclePosition current_vehicle_position;
|
||
extern std::mutex vehicle_position_mutex;
|
||
|
||
extern ExtremeData current_extreme_data;
|
||
extern std::mutex extreme_data_mutex;
|
||
|
||
extern AlarmData current_alarm_data;
|
||
extern std::mutex alarm_data_mutex;
|
||
|
||
extern StorageVoltageData current_storage_voltage_data;
|
||
extern std::mutex storage_voltage_mutex;
|
||
|
||
extern StorageTempData current_storage_temp_data;
|
||
extern std::mutex storage_temp_mutex;
|
||
|
||
extern std::vector<uint8_t> current_autodata;
|
||
extern std::mutex autodata_mutex;
|
||
|
||
extern DriveBrakeData current_drive_brake_data;
|
||
extern std::mutex drive_brake_mutex;
|
||
|
||
extern TireData current_tire_data;
|
||
extern std::mutex tire_data_mutex;
|
||
|
||
extern FrontSwitchData current_front_switch_data;
|
||
extern std::mutex front_switch_mutex;
|
||
|
||
extern VehicleFullData current_vehicle_full_data;
|
||
extern std::mutex vehicle_full_mutex;
|
||
|
||
void handle_can_msg(const can_frame& frame); // 处理 CAN 消息
|
||
std::vector<uint8_t> buildTboxRealtimePayload();
|