ARS_408毫米波雷达数据解析学习记录-协议部分

本文主要是记录ARS_408毫米波雷达协议解读与简单实现过程。仍在学习过程中,难免存在理解误区,欢迎批评指正,共同进步。

引言:

传感器发送和接收的CAN信息类型如下表所示,下面主要用到的协议包括2个输入信息部分(RadarCfg 和 Motion Input Signals)和3个输出信息部分(RadarState 以及Cluster List 和Object List)。
在这里插入图片描述

1、RadarCfg部分

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

  • 定义Union共用体变量用于存储数据
namespace radar_cfg {
typedef union radar_cfg {
  struct {		// ":"表示机构内位域的定义,即该变量占几个bit空间
    uint64_t RadarCfg_MaxDistance_valid:1;	
    uint64_t RadarCfg_SensorID_valid:1;
    uint64_t RadarCfg_RadarPower_valid:1;
    uint64_t RadarCfg_OutputType_valid:1;
    uint64_t RadarCfg_SendQuality_valid:1;
    uint64_t RadarCfg_SendExtInfo_valid:1;
    uint64_t RadarCfg_SortIndex_valid:1;
    uint64_t RadarCfg_StoreInNVM_valid:1;
    uint64_t RadarCfg_MaxDistance1:8;
    uint64_t Reserved:6;
    uint64_t RadarCfg_MaxDistance2:2;
    uint64_t Reserved2:8;
    uint64_t RadarCfg_SensorID:3;
    uint64_t RadarCfg_OutputType:2;
    uint64_t RadarCfg_RadarPower:3;
    uint64_t RadarCfg_CtrlRelay_valid:1;
    uint64_t RadarCfg_CtrlRelay:1;
    uint64_t RadarCfg_SendQuality:1;
    uint64_t RadarCfg_SendExtInfo:1;
    uint64_t RadarCfg_SortIndex:3;
    uint64_t RadarCfg_StoreInNVM:1;
    uint64_t RadarCfg_RCS_Threshold_valid:1;
    uint64_t RadarCfg_RCS_Threshold:3;
    uint64_t Reserved3:4;
    uint64_t Reserved4:8;
  } data = {};
  uint8_t raw_data[8];
} radar_cfg;
}
  • 定义RadarCfg类
namespace radar_cfg {
class RadarCfg {
 public:
  RadarCfg();
  ~RadarCfg();
  bool set_max_distance(uint64_t distance, bool valid = true);  //最大距离
  bool set_sensor_id(int id, bool valid = true);		//传感器ID
  bool set_radar_power(int power, bool valid = true);	//雷达发射功率
  bool set_output_type(int output_type, bool valid = true); //数据输出模式
  void set_send_quality(bool quality, bool valid = true);	//quality信息
  void set_send_ext_info(bool send_ext, bool valid = true);	//Extended信息
  bool set_sort_index(int sort_index, bool valid = true); //为object list选择排序索引(clusters list默认按照距离进行排列)
  void set_ctrl_relay_cfg(bool ctrl_relay, bool valid = true);  //Relay control message
  void set_store_in_nvm(bool store_in_nvm, bool valid = true);	//将配置信息保存到non-volatile memory(NVM),以便传感器启动时读取和配置
  bool set_rcs_threshold(int rcs_threshold, bool valid = true);	//cluster检测的灵敏度设置,标准(0x0)或高灵敏度(0x1)
  radar_cfg *get_radar_cfg();
 private:
  radar_cfg radar_cfg_msg;
};
}
  • RadarCfg类的实现
namespace radar_cfg {
RadarCfg::RadarCfg() {
  radar_cfg_msg.data.RadarCfg_MaxDistance_valid = 0;
  radar_cfg_msg.data.RadarCfg_SensorID_valid = 0;
  radar_cfg_msg.data.RadarCfg_RadarPower_valid = 0;
  radar_cfg_msg.data.RadarCfg_OutputType_valid = 0;
  radar_cfg_msg.data.RadarCfg_SendQuality_valid = 0;
  radar_cfg_msg.data.RadarCfg_SendExtInfo_valid = 0;
  radar_cfg_msg.data.RadarCfg_SortIndex_valid = 0;
  radar_cfg_msg.data.RadarCfg_CtrlRelay_valid = 0;
  radar_cfg_msg.data.RadarCfg_StoreInNVM_valid = 0;
  radar_cfg_msg.data.RadarCfg_RCS_Threshold_valid = 0;
}
RadarCfg::~RadarCfg() {
}
bool RadarCfg::set_max_distance(uint64_t distance, bool valid) {
  if (distance < 90 || distance > 1000) {
    return false;		//Extended Range  ARS408:196m~1200m  ARS404:90m~1000m
  }
  distance /= 2;
  radar_cfg_msg.data.RadarCfg_MaxDistance1 = distance >> 2;  // 二进制值按位右移2位,表示取数据的去掉2位后的高位部分
  radar_cfg_msg.data.RadarCfg_MaxDistance2 = distance & 0b11;	//取数据的最后2位地位部分
  radar_cfg_msg.data.RadarCfg_MaxDistance_valid = static_cast<uint64_t>(valid);
  return true;
}
bool RadarCfg::set_sensor_id(int id, bool valid) {
  if (id < 0 || id > 7) {
    return false;
  }
  radar_cfg_msg.data.RadarCfg_SensorID = static_cast<uint64_t>(id);
  radar_cfg_msg.data.RadarCfg_SensorID_valid = static_cast<uint64_t>(valid);
  return true;
}
bool RadarCfg::set_radar_power(int power, bool valid) {
  if (power < 0 || power > 3) {		
    return false;  	//0x0: Standard  0x1: -3dB Tx gain  0x2: -6dB Tx gain  0x3: -9dB Tx gain
  }
  radar_cfg_msg.data.RadarCfg_RadarPower = static_cast<uint64_t>(power);
  radar_cfg_msg.data.RadarCfg_RadarPower_valid = static_cast<uint64_t>(valid);
  return true;
}
bool RadarCfg::set_output_type(int output_type, bool valid) {
  if (output_type < 0 || output_type > 2) {		//Clusters (0x2) or Objects (0x1) or “Stand By” (0x0)
    return false;
  }
  radar_cfg_msg.data.RadarCfg_OutputType = static_cast<uint64_t>(output_type);
  radar_cfg_msg.data.RadarCfg_OutputType_valid = static_cast<uint64_t>(valid);
  return true;
}
void RadarCfg::set_send_quality(bool quality, bool valid) {
  radar_cfg_msg.data.RadarCfg_SendQuality = static_cast<uint64_t>(quality);
  radar_cfg_msg.data.RadarCfg_SendQuality_valid = static_cast<uint64_t>(valid);		//Cluster or object quality information (message 0x60C or 0x702) is sent if true
}
void RadarCfg::set_send_ext_info(bool send_ext, bool valid) {
  radar_cfg_msg.data.RadarCfg_SendExtInfo = static_cast<uint64_t>(send_ext);
  radar_cfg_msg.data.RadarCfg_SendExtInfo_valid = static_cast<uint64_t>(valid);		//Extended information (message 0x60D) is sent for objects if true (if clusters are selected as output type this value is ignored)
}
bool RadarCfg::set_sort_index(int sort_index, bool valid) {
  if (sort_index < 0 || sort_index > 2) {
    return false;	//Selects the sorting index for the object list (ignored for clusters as they are always sorted by range)
  }
  radar_cfg_msg.data.RadarCfg_SortIndex = static_cast<uint64_t>(sort_index);
  radar_cfg_msg.data.RadarCfg_SortIndex_valid = static_cast<uint64_t>(valid);
  return true;
}
void RadarCfg::set_ctrl_relay_cfg(bool ctrl_relay, bool valid) {
  radar_cfg_msg.data.RadarCfg_CtrlRelay = static_cast<uint64_t>(ctrl_relay);
  radar_cfg_msg.data.RadarCfg_CtrlRelay_valid = static_cast<uint64_t>(valid);		//Relay control message (0x8) is sent if true and the collision detection is activated
}
void RadarCfg::set_store_in_nvm(bool store_in_nvm, bool valid) {
  radar_cfg_msg.data.RadarCfg_StoreInNVM = static_cast<uint64_t>(store_in_nvm);
  radar_cfg_msg.data.RadarCfg_StoreInNVM_valid = static_cast<uint64_t>(valid);		//Stores the current configuration to non-volatile memory to be read and set at sensor startup
}
bool RadarCfg::set_rcs_threshold(int rcs_threshold, bool valid) {
  if (rcs_threshold != 0 && rcs_threshold != 1) {
    return false;	//Sets the sensitivity of the cluster detection to standard (0x0) or high sensitivity (0x1)
  }
  radar_cfg_msg.data.RadarCfg_RCS_Threshold = static_cast<uint64_t>(rcs_threshold);
  radar_cfg_msg.data.RadarCfg_RCS_Threshold_valid = static_cast<uint64_t>(valid);
  return true;
}
radar_cfg *RadarCfg::get_radar_cfg() {
  return &radar_cfg_msg;
}
}
2、RadarState部分
  • RadarState(0x201)消息是由传感器周期性的发送,每秒一次。在RadarCfg(0x200)参数配置后,可以检查消息0x201中的相应信号,以确认配置更改是否已完成。

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

  • 定义Union共用体用于存储数据
namespace radar_state {
typedef union radar_state {
  struct {
    uint64_t Reserved:6;
    uint64_t RadarState_NVMReadStatus:1;
    uint64_t RadarState_NVMwriteStatus:1;
    uint64_t RadarState_MaxDistanceCfg1:8;
    uint64_t Reserved2:1;
    uint64_t RadarState_Voltage_Error:1;
    uint64_t RadarState_Temporary_Error:1;
    uint64_t RadarState_Temperature_Error:1;
    uint64_t RadarState_Interference:1;
    uint64_t RadarState_Persistent_Error:1;
    uint64_t RadarState_MaxDistanceCfg2:2;
    uint64_t RadarState_RadarPowerCfg1:2;
    uint64_t Reserved3:6;
    uint64_t RadarState_SensorID:3;
    uint64_t Reserved4:1;
    uint64_t RadarState_SortIndex:3;
    uint64_t RadarState_RadarPowerCfg2:1;
    uint64_t Reserved5:1;
    uint64_t RadarState_CtrlRelayCfg:1;
    uint64_t RadarState_OutputTypeCfg:2;
    uint64_t RadarState_SendQualityCfg:1;
    uint64_t RadarState_SendExtInfoCfg:1;
    uint64_t RadarState_MotionRxState:2;
    uint64_t Reserved6:8;
    uint64_t Reserved7:2;
    uint64_t RadarState_RCS_Threshold:3;
    uint64_t Reserved8:3;
  } data = {};
  uint8_t raw_data[8];
} radar_state;
}
  • 定义RadarState类
namespace radar_state {
class RadarState {
 public:
  RadarState();
  ~RadarState();
  bool get_read_status();	//启动时从 NVM 中读取配置参数的结果状态
  bool get_write_status();	//将配置参数保存到 NVM 中的结果状态
  uint64_t get_max_distance();	//当前far scan最大距离的配置参数
  bool get_persistent_error_status();	//检测到复位后可能不会消失的内部错误
  bool get_interference_status();	//检测到与另一个雷达传感器的干扰
  bool get_temperature_error_status();	//如果温度低于或高于定义的范围,错误将激活。离开后会自动退出
  bool get_temporary_error_status();	//检测到传感器复位后最有可能消失的临时错误
  bool get_voltage_error_status();	//如果工作电压低于或高于规定范围5秒以上,则错误将激活
  int get_sensor_id();	//当前传感器ID (0-7)
  int get_sort_index();	//当前目标列表的排序方式0x0: no sorting 0x1: sorted by range	0x2: sorted by RCS
  int get_radar_power_cfg();	//当前雷达发射功率的参数配置0x0: Standard 0x1: -3dB Tx gain 0x2: -6dB Tx gain 0x3: -9dB Tx gain
  bool get_ctrl_relay_cfg();	//0x0: inactive  0x1: active
  int get_output_type_cfg();	//当前输出模式为Clusters 或者Objects
  bool get_send_quality_cfg();	//0x0: inactive  0x1: active
  bool get_ext_info_cfg();		//0x0: inactive  0x1: active
  int get_motion_rx_state();	//显示速度和角速度输入信号的状态,0x0: input ok  0x1: speed missing  0x2: yaw rate missing  0x3: speed and yaw rate missing
  int get_rcs_threshold();		//0x0 Standard	0x1 High sensitivity
  radar_state *get_radar_state();
 private:
  radar_state radar_state_msg;
};
}
  • RadarState类的实现
namespace radar_state {
RadarState::RadarState() {
}
RadarState::~RadarState() {
}
bool RadarState::get_read_status() {
  return static_cast<bool>(radar_state_msg.data.RadarState_NVMReadStatus);
}
bool RadarState::get_write_status() {
  return static_cast<bool>(radar_state_msg.data.RadarState_NVMwriteStatus);
}
uint64_t RadarState::get_max_distance() {
  return (radar_state_msg.data.RadarState_MaxDistanceCfg1 << 2 |
      radar_state_msg.data.RadarState_MaxDistanceCfg2) * 2;
}	//数据在Union的存储位置是二进制位中的22-23位(cfg2),8-15位(cfg1),取数据时是cfg1和cfg2的拼接结果*2
bool RadarState::get_persistent_error_status() {
  return static_cast<bool>(radar_state_msg.data.RadarState_Persistent_Error);
}
bool RadarState::get_interference_status() {
  return static_cast<bool>(radar_state_msg.data.RadarState_Interference);
}
bool RadarState::get_temperature_error_status() {
  return static_cast<bool>(radar_state_msg.data.RadarState_Temperature_Error);
}
bool RadarState::get_temporary_error_status() {
  return static_cast<bool>(radar_state_msg.data.RadarState_Temporary_Error);
}
bool RadarState::get_voltage_error_status() {
  return static_cast<bool>(radar_state_msg.data.RadarState_Voltage_Error);
}
int RadarState::get_sensor_id() {
  return static_cast<int>(radar_state_msg.data.RadarState_SensorID);
}
int RadarState::get_sort_index() {
  return static_cast<int>(radar_state_msg.data.RadarState_SortIndex);
}
int RadarState::get_radar_power_cfg() {
  return static_cast<int>((radar_state_msg.data.RadarState_RadarPowerCfg1 << 1)
        | radar_state_msg.data.RadarState_RadarPowerCfg2);
}
bool RadarState::get_ctrl_relay_cfg() {
  return static_cast<bool>(radar_state_msg.data.RadarState_CtrlRelayCfg);
}
int RadarState::get_output_type_cfg() {
  return static_cast<int>(radar_state_msg.data.RadarState_OutputTypeCfg);
}
bool RadarState::get_send_quality_cfg() {
  return static_cast<bool>(radar_state_msg.data.RadarState_SendQualityCfg);
}
bool RadarState::get_ext_info_cfg() {
  return static_cast<bool>(radar_state_msg.data.RadarState_SendExtInfoCfg);
}
int RadarState::get_motion_rx_state() {
  return static_cast<int>(radar_state_msg.data.RadarState_MotionRxState);
}
int RadarState::get_rcs_threshold() {
  return static_cast<int>(radar_state_msg.data.RadarState_RCS_Threshold);
}
radar_state *RadarState::get_radar_state() {
  return &radar_state_msg;
}
}
3、Motion Input Signals部分
  • 传感器接收输入信号 0x3000x301,但在没有这两部分信号信息的的情况下仍能正常工作。超时***500ms***后,传感器将其默认为以下状态:

    • Speed 0 m/s 和 standstill
    • Yaw rate 0 deg/s
  • 每条消息都有独立的超时监听。超时状态反映在信号***RadarState_MotionRxState (0x201)*** 中。

  • 输入信号用于评估车辆行驶路线,并用于确定检测到的 Clusters 和 Objects 的移动。

在这里插入图片描述

在这里插入图片描述

  • 定义用于存储数据的Union共用体和enum变量
namespace motion_input_signals {
typedef union speed_information {
  struct {
    uint64_t RadarDevice_Speed1:5;
    uint64_t Reserved:1;
    uint64_t RadarDevice_SpeedDirection:2;
    uint64_t RadarDevice_Speed2:8;
  } data = {};
  uint8_t raw_data[2];
} speed_information;
typedef enum RadarDevice_SpeedDirection {	//指示雷达移动的方向,参照前进方向
  STANDSTILL = 0x0,
  FORWARD = 0x1,
  BACKWARD = 0x2,			
} RadarDevice_SpeedDirection;
typedef union yaw_rate_information {	//参照前进方向角速度的变化率。假设旋转中心位于传感器后面1.95 m处。
  struct {
    uint64_t RadarDevice_YawRate1:8;
    uint64_t RadarDevice_YawRate2:8;
  } data = {};
  uint8_t raw_data[2];
} yaw_rate_information;
}
  • ***SpeedInformation***类和***YawRateInformation***类的定义
namespace motion_input_signals {
class SpeedInformation {
 public:
  SpeedInformation();
  ~SpeedInformation();
  void set_speed(double speed);
  void set_speed_direction(RadarDevice_SpeedDirection direction);
  speed_information *get_speed_information();
 private:
  speed_information speed_information_msg;
};
class YawRateInformation {
 public:
  YawRateInformation();
  ~YawRateInformation();
  void set_yaw_rate(double yaw_rate);
  yaw_rate_information *get_yaw_rate_information();
 private:
  speed_information speed_information_msg;
  yaw_rate_information yaw_rate_information_msg;
};
}  
  • 类的实现
namespace motion_input_signals {
SpeedInformation::SpeedInformation() {
}
SpeedInformation::~SpeedInformation() {
}
void SpeedInformation::set_speed(double speed) {
  int radar_speed = static_cast<int>(speed / 0.02);		//表中Res为0.02
  speed_information_msg.data.RadarDevice_Speed1 = static_cast<uint64_t>(radar_speed >> 8);	//存储位置方向从8-15位,0-4位。>>8表示取出数据中的高位部分,存储到0-4位;
  speed_information_msg.data.RadarDevice_Speed2 = static_cast<uint64_t>(radar_speed & 255);		//&255表示取出数据低位的8位数据,存储到8-15位。
}
void SpeedInformation::set_speed_direction(RadarDevice_SpeedDirection direction) {
  speed_information_msg.data.RadarDevice_SpeedDirection = direction;
}
speed_information *SpeedInformation::get_speed_information() {
  return &speed_information_msg;
}
YawRateInformation::YawRateInformation() {
}
YawRateInformation::~YawRateInformation() {
}
void YawRateInformation::set_yaw_rate(double yaw_rate) {
  int radar_yaw_rate = static_cast<int>((yaw_rate + 327.68) / 0.01);//表中Offset为 +327.68,Res为0.01
  yaw_rate_information_msg.data.RadarDevice_YawRate1 = static_cast<uint64_t>(radar_yaw_rate >> 8);	//数据存储位置从8-15位,0-8位。 >>8表示取出数据的取出8二进制位之前的高位数据,存储到0-8位;
  yaw_rate_information_msg.data.RadarDevice_YawRate2 = static_cast<uint64_t>(radar_yaw_rate & 255);	//&255表示取出数据的低8位部分,存储到8-15位。
}
yaw_rate_information *YawRateInformation::get_yaw_rate_information() {
  return &yaw_rate_information_msg;
}
}
4、Cluster List部分
  • 首先基于对象的反射信号创建簇(clusters)。每个粒子将被检测为簇。最近的粒子将是第一个被检测到并被带到结合点的粒子。随着集群(clusters)数量的增加,距离也会增加。
  • 如果在信号***RadarCfg_OutputType*** (0x200) 中选择了***clusters*** 模式,Cluster list的输出由三种消息定义,这些消息以固定间隔(大约70-80 ms)发送。
    • Cluster_0_Status (0x600) — 第一部分消息包含列表头信息,即之后要发送的近扫描clusters 的数目和远扫描 clusters 的数目;
    • Cluster_1_General (0x701) — 此消息包含 clusters 的位置和速度,并针对所有检测到的 clusters 重复发送(首先是近扫描,然后是远扫描)。两个集群列表中的每一个都是距离排序的。 如果超过 250 个 clusters,则只发送前 250 个 clusters。
    • Cluster_2_Quality (0x702) — 此消息包含 clusters 的质量信息,并且仅当它在信号***RadarCfg_SendQuality*** (0x200) 中被激活时才会发送。它以与消息 Cluster_1_General (0x701) 相同的方式为所有 clusters 重复发送。
    • 如果发送质量信息,首先发送所有类型为 Cluster_1_General (0x701) 的消息,然后发送所有类型为 Cluster_2_Quality (0x702) 的消息。

在这里插入图片描述

4.1、Cluster list status (0x600)
  • 这部分包含 cluster 列表头信息,作为 cluster 列表输出的第一条消息发送,且每个测量周期仅发送一次。

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

  • 定义用于存储数据的Union
namespace cluster_list {
typedef union cluster_0_status {
  struct {
    uint64_t Cluster_NofClustersNear:8;
    uint64_t Cluster_NofClustersFar:8;
    uint64_t Cluster_MeasCounter1:8;
    uint64_t Cluster_MeasCounter2:8;
    uint64_t Reserved:4;
    uint64_t Cluster_InterfaceVersion:4;
  } data = {};
  uint8_t raw_data[5];
} cluster_0_status;
}
  • 定义Cluster_0_Status类
namespace cluster_list {
class Cluster_0_Status {
 public:
  Cluster_0_Status();
  ~Cluster_0_Status();
  int get_no_of_clusters_near();	//获取近扫描点数
  int get_no_of_clusters_far();		//获取远扫描点数。近扫和远扫一起最多250个clusters。如何激活quality模块,为避免CAN总线超限,将最大 clusters数量限制为 125
  int get_measurement_cycle_counter();		//获取测量周期计数,从传感器启动开始向上计数,当 > 65535 时从 0 重新开始
  int get_interface_version();	//Cluster列表 CAN 接口版本号。在未更改Cluster标识符之前,它始终为“1”
  cluster_0_status *get_cluster_0_status();
 private:
  cluster_0_status cluster_0_status_msg;
};
}
  • Cluster_0_Status类的实现
namespace cluster_list {
Cluster_0_Status::Cluster_0_Status() {
}
Cluster_0_Status::~Cluster_0_Status() {
}
int Cluster_0_Status::get_no_of_clusters_near() {
  return static_cast<int>(cluster_0_status_msg.data.Cluster_NofClustersNear);
}
int Cluster_0_Status::get_no_of_clusters_far() {
  return static_cast<int>(cluster_0_status_msg.data.Cluster_NofClustersFar);
}
int Cluster_0_Status::get_measurement_cycle_counter() {
  return static_cast<int>(cluster_0_status_msg.data.Cluster_MeasCounter1 << 8
      | cluster_0_status_msg.data.Cluster_MeasCounter2);
}		// <<8 表示获取数据8位以外的高位部分, | MeasCounter2表示获取数据的后8位
int Cluster_0_Status::get_interface_version() {
  return static_cast<int>(cluster_0_status_msg.data.Cluster_InterfaceVersion);
}
cluster_0_status *Cluster_0_Status::get_cluster_0_status() {
  return &cluster_0_status_msg;
}
}
4.2、Cluster general information (0x701)
  • 该消息包含 clusters 的位置和速度,并针对所有检测到的 clusters 重复发送(首先是近扫描,然后是远扫描)。 两个集群列表中的每一个都是距离排序的。 如果超过 250 个clusters,则只发送前 250 个clusters。

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

  • 定义用于存储数据的Union
namespace cluster_list {
typedef union cluster_1_general {
  struct {
    uint64_t Cluster_ID:8;
    uint64_t Cluster_DistLong1:8;
    uint64_t Cluster_DistLat1:2;
    uint64_t Reserved:1;
    uint64_t Cluster_DistLong2:5;
    uint64_t Cluster_DistLat2:8;
    uint64_t Cluster_VrelLong1:8;
    uint64_t Cluster_VrelLat1:6;
    uint64_t Cluster_VrelLong2:2;
    uint64_t Cluster_DynProp:3;
    uint64_t Reserved2:2;
    uint64_t Cluster_VrelLat2:3;
    uint64_t Cluster_RCS:8;
  } data = {};
  uint8_t raw_data[8];
} cluster_1_general;
}
  • 定义 Cluster_1_General类
namespace cluster_list {
class Cluster_1_General {
 public:
  Cluster_1_General();
  ~Cluster_1_General();
  int get_cluster_id();		//获取 Cluster number
  double get_cluster_long_dist();	//获取Longitudinal(x)坐标	单位:m
  double get_cluster_lat_dist();	//获取Lateral(y)坐标	单位:m
  double get_cluster_long_rel_vel();	//获取 x 方向的相对速度	单位:m/s
  double get_cluster_lat_rel_vel();		//获取 y 方向的相对速度,该值恒置为0	单位:m/s
  int get_cluster_dyn_prop();		//获取cluster的动态属性,来表示其是否在移动。0x0:moving  0x1:stationary  0x2:oncoming  0x3:stationary candidate  0x4:unknown  0x5:crossing stationary  0x6:crossing moving  0x7:stopped
  double get_cluster_rcs();			//RCS(Radar cross section)雷达散射截面	单位:dBm2
  cluster_1_general *get_cluster_1_general();
 private:
  cluster_1_general cluster_1_general_msg;
};
}
  • Cluster_1_General类实现
namespace cluster_list {
Cluster_1_General::Cluster_1_General() {
}
Cluster_1_General::~Cluster_1_General() {
}
int Cluster_1_General::get_cluster_id() {
  return static_cast<int>(cluster_1_general_msg.data.Cluster_ID);
}
double Cluster_1_General::get_cluster_long_dist() {
  return (cluster_1_general_msg.data.Cluster_DistLong1 << 5 |
      cluster_1_general_msg.data.Cluster_DistLong2) * 0.2 - 500.0;
}	//存储位置为19-23位,8-15位。<<5取的是数据8-15位的高位部分,| 取的是数据19-23位的低位部分。Offset为 -500,Res为 0.2。
double Cluster_1_General::get_cluster_lat_dist() {
  return (cluster_1_general_msg.data.Cluster_DistLat1 << 8 |
      cluster_1_general_msg.data.Cluster_DistLat2) * 0.2 - 102.3;
}	//存储位置为24-31位,16-17位。<<8取的是数据16-17位的高位部分,| 取的是数据24-31位的低位部分。Offset为 -102.3,Res为 0.2。
double Cluster_1_General::get_cluster_long_rel_vel() {
  return (cluster_1_general_msg.data.Cluster_VrelLong1 << 2 |
      cluster_1_general_msg.data.Cluster_VrelLong2) * 0.25 - 128.0;
}	//存储位置为46-47位,32-39位。<<2取的是数据32-39位的高位部分,| 取的是数据46-47位的低位部分。Offset为 -128.00,Res位 0.25。
double Cluster_1_General::get_cluster_lat_rel_vel() {
  return (cluster_1_general_msg.data.Cluster_VrelLat1 << 3 |
      cluster_1_general_msg.data.Cluster_VrelLat2) * 0.25 - 64.0;
}	//存储位置为53-55位,40-45位。<<3取的是数据40-45位的高位部分,| 取的是数据53-55位的低位部分。Offset为 -64.00,Res位 0.25。
int Cluster_1_General::get_cluster_dyn_prop() {
  return static_cast<int>(cluster_1_general_msg.data.Cluster_DynProp);
}
double Cluster_1_General::get_cluster_rcs() {
  return cluster_1_general_msg.data.Cluster_RCS * 0.5 - 64.0;
}	//Offset为 -64.0,Res为 0.5。
cluster_1_general *Cluster_1_General::get_cluster_1_general() {
  return &cluster_1_general_msg;
}
}
4.3、Cluster quality information (0x702)
  • 该消息包含 clusters 的质量信息,只有在信号***RadarCfg_SendQuality*** (0x200) 中激活时才发送。它以与消息***Cluster_1_General*** (0x701)相同的方式为所有 clusters 重复发送。如果此消息被激活,则必须通过 filter 或 environment 将最大 clusters 数量限制为 125

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

  • 定义用于存储数据的 Union
namespace cluster_list {
typedef union cluster_2_quality {
  struct {
    uint64_t Cluster_ID:8;
    uint64_t Cluster_DistLat_rms1:3;
    uint64_t Cluster_DistLong_rms:5;
    uint64_t Cluster_VrelLat_rms1:1;
    uint64_t Cluster_VrelLong_rms:5;
    uint64_t Cluster_DistLat_rms2:2;
    uint64_t Cluster_Pdh0:3;
    uint64_t Reserved:1;
    uint64_t Cluster_VrelLat_rms2:4;
    uint64_t Cluster_AmbigState:3;
    uint64_t Cluster_InvalidState:5;
  } data = {};
  uint8_t raw_data[5];
} cluster_2_quality;
}
  • 定义 Cluster_2_Quality类
namespace cluster_list {
class Cluster_2_Quality {
 public:
  Cluster_2_Quality();
  ~Cluster_2_Quality();
  int get_cluster_id();		//获取 Cluster number
  double get_cluster_long_dist_rms();	//获取Longitudinal(x)坐标标准差	单位:m
  double get_cluster_long_rel_vel_rms();	//获取 x 方向的相对速度的标准差	单位:m/s
  double get_cluster_lat_dist_rms();	//获取Lateral(y)坐标标准差		单位:m
  int get_cluster_pdh0();	//获取Cluster的虚警概率,(即由多径或类似引起的虚假的概率)
  double get_cluster_lat_rel_vel_rms();	//获取 y 方向的相对速度的标准差	单位:m/s
  int get_cluster_ambiguity_state();	//获取多普勒(径向速度)模糊解的状态
  int get_cluster_validity_state();		//获取Cluster有效性的状态
  cluster_2_quality *get_cluster_2_quality();
 private:
  cluster_2_quality cluster_2_quality_msg;
  double signal_value_table[32] = {
      0.005, 0.006, 0.008, 0.011,
      0.014, 0.018, 0.023, 0.029,
      0.038, 0.049, 0.063, 0.081,
      0.105, 0.135, 0.174, 0.224,
      0.288, 0.371, 0.478, 0.616,
      0.794, 1.023, 1.317, 1.697,
      2.187, 2.817, 3.630, 4.676,
      6.025, 7.762, 10.000
  };	//(0x702)中Cluster_DistLong_rms, Cluster_DistLat_rms [m] 	Cluster_VrelLong_rms, Cluster_VrelLat_rms [m/s]的信号值表
};
}
5、Object List部分
  • Objects是由雷达构建的第二个元素(the history of the clusters)。换句话说,objects是我们感兴趣的真正主体,可以定义为一连串反射信号的合成。最近的Object将首先建立,以此类推。随着objects数量的增加,距离也在增加。

  • 如果在信号***RadarCfg_OutputType*** (0x200) 中选择了***objects*** 模式,Object list的输出由五种消息定义,这些消息以固定间隔发送。

    • Object_0_Status (0x60A) — 第一部分消息包含列表头信息,即之后要发送的 objects的数目;
    • Object_1_General (0x60B) — 此消息包含 objects 的位置和速度,并为所有被跟踪的 objects 重复发送。
    • Object_2_Quality (0x60C) — 此消息包含 objects 的质量信息,并且仅当它在信号***RadarCfg_SendQuality*** (0x200) 中被激活时才会发送。它以与消息 Object_1_General (0x60B) 相同的方式为所有 objects 重复发送。
    • Object_3_Extended (0x60D) — 此消息包含 object 的扩展属性,并且仅当它在信号***RadarCfg_SendExtInfo*** (0x200) 中被激活时才会发送。它以与消息 Object_1_General (0x60B) 相同的方式为所有 objects 重复发送。
    • Object_4_Warning (0x60E) — 此消息包含碰撞检测警告状态,仅当碰撞检测在消息 CollDetCfg (0 x400) 中被激活时发送。它以与消息 Object_1_General (0x60B) 相同的方式为所有 objects 重复发送。
    • 如果发送质量信息、扩展信息和/或警告状态,首先发送所有类型为***Object_1_General*** (0x60B)的消息,然后发送所有类型为***Object_2_Quality*** (0x60C)的消息,然后发送类型为***Object_3_Extended*** (0x60D)的消息和/或之后发送类型为***Object_4_Warning*** (0x60E)的消息。

在这里插入图片描述

5.1、Object list status (0x60A)
  • 消息***Object_0_Status*** (0x60A)包含 object 列表头信息,并作为 cluster 列表输出的第一个消息发送,并且每个测量周期只发送一次。

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

  • 定义用于存储数据的Union
namespace object_list {
typedef union object_0_status {
  struct {
    uint64_t Object_NofObjects:8;
    uint64_t Object_MeasCounter1:8;
    uint64_t Object_MeasCounter2:8;
    uint64_t Reserved:4;
    uint64_t Object_InterfaceVersion:4;
  } data = {};

  uint8_t raw_data[4];
} object_0_status;
}
  • 定义 Object_0_Status 类
namespace object_list {
class Object_0_Status {
 public:
  Object_0_Status();
  ~Object_0_Status();
  int get_no_of_objects();		//获取objects的数量(最大为100)
  int get_measurement_cycle_counter();	//获取测量周期计数,从传感器启动开始向上计数,当 > 65535 时从 0 重新开始
  int get_interface_version();	//Object列表 CAN 接口版本号。在未更改Object标识符之前,它始终为“1”。
  object_0_status *get_object_0_status();	
 private:
  object_0_status object_0_status_msg;
};
}
  • Object_0_Status 类的实现
namespace object_list {
Object_0_Status::Object_0_Status() {
}
Object_0_Status::~Object_0_Status() {
}
int Object_0_Status::get_no_of_objects() {
  return static_cast<int>(object_0_status_msg.data.Object_NofObjects);
}
int Object_0_Status::get_measurement_cycle_counter() {
  return static_cast<int>(object_0_status_msg.data.Object_MeasCounter1 << 8
      | object_0_status_msg.data.Object_MeasCounter2);
}	//存储位置从18-23位,8-15位。 <<8得到的是8位以外的高位数据,| 得到的是低8位数据
int Object_0_Status::get_interface_version() {
  return static_cast<int>(object_0_status_msg.data.Object_InterfaceVersion);
}
object_0_status *Object_0_Status::get_object_0_status() {
  return &object_0_status_msg;
}
}
5.2、Object general information (0x60B)
  • 此消息包含 objects 的位置和速度,并为所有被跟踪的 objects 重复发送。

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

  • 定义用于存储数据的Union
namespace object_list {
typedef union object_1_general {
  struct {
    uint64_t Object_ID:8;
    uint64_t Object_DistLong1:8;
    uint64_t Object_DistLat1:3;
    uint64_t Object_DistLong2:5;
    uint64_t Object_DistLat2:8;
    uint64_t Object_VrelLong1:8;
    uint64_t Object_VrelLat1:6;
    uint64_t Object_VrelLong2:2;
    uint64_t Object_DynProp:3;
    uint64_t Reserved:2;
    uint64_t Object_VrelLat2:3;
    uint64_t Object_RCS:8;
  } data = {};
  uint8_t raw_data[8];
} object_1_general;
}
  • 定义 Object_1_General 类
namespace object_list {
class Object_1_General {
 public:
  Object_1_General();
  ~Object_1_General();
  int get_object_id();	//ObjectID(因为objects是被跟踪的,所以ID会在整个测量周期中保持,并且不必是连续的)
  double get_object_long_dist();	//获取Longitudinal(x)坐标	单位:m
  double get_object_lat_dist();		//获取Lateral(y)坐标	单位:m
  double get_object_long_rel_vel();	//获取Longitudinal(x)方向相对速度	单位:m/s
  int get_object_dyn_prop();		//object的动态属性,表示object是运动的还是静止的(只有在正确给出speed和yaw rate时,才能正确确定该值)。0x0:moving  0x1:stationary  0x2:oncoming  0x3:stationary candidate  0x4:unknown  0x5:crossing stationary  0x6:crossing moving  0x7:stopped
  double get_object_lat_rel_vel();	//获取Lateral(y)方向相对速度	单位:m/s
  double get_object_rcs();			//RCS(Radar cross section)雷达散射截面	单位:dBm2
  object_1_general *get_object_1_general();
 private:
  object_1_general object_1_general_msg;
};
}
  • Object_1_General 类的实现
namespace object_list {
Object_1_General::Object_1_General() {
}
Object_1_General::~Object_1_General() {
}
int Object_1_General::get_object_id() {
  return static_cast<int>(object_1_general_msg.data.Object_ID);
}
double Object_1_General::get_object_long_dist() {
  return (object_1_general_msg.data.Object_DistLong1 << 5 |
      object_1_general_msg.data.Object_DistLong2) * 0.2 - 500.0;
}	//Offset为 -500,Res为 0.2
double Object_1_General::get_object_lat_dist() {
  return (object_1_general_msg.data.Object_DistLat1 << 8 |
      object_1_general_msg.data.Object_DistLat2) * 0.2 - 204.6;
}	//Offset为 -204.6,Res为 0.2
double Object_1_General::get_object_long_rel_vel() {
  return (object_1_general_msg.data.Object_VrelLong1 << 2 |
      object_1_general_msg.data.Object_VrelLong2) * 0.25 - 128.0;
}	//Offset为 -128.0,Res为 0.25
double Object_1_General::get_object_lat_rel_vel() {
  return (object_1_general_msg.data.Object_VrelLat1 << 3 |
      object_1_general_msg.data.Object_VrelLat2) * 0.25 - 64.0;
}	//Offset为 -64.0,Res为 0.25
int Object_1_General::get_object_dyn_prop() {
  return static_cast<int>(object_1_general_msg.data.Object_DynProp);
}
double Object_1_General::get_object_rcs() {
  return object_1_general_msg.data.Object_RCS * 0.5 - 64.0;
}	//Offset为 -64,Res为 0.5
object_1_general *Object_1_General::get_object_1_general() {
  return &object_1_general_msg;
}
}
5.3、Object quality information (0x60C)
  • 此消息包含 objects 的质量信息,并且仅当它在信号***RadarCfg_SendQuality*** (0x200) 中被激活时才会发送。它以与消息 Object_1_General (0x60B) 相同的方式为所有 objects 重复发送。

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

  • 定义用于存储数据的Union
namespace object_list {
typedef union object_2_quality {
  struct {
    uint64_t Obj_ID:8;
    uint64_t Obj_DistLat_rms1:3;
    uint64_t Obj_DistLong_rms:5;
    uint64_t Obj_VrelLat_rms1:1;
    uint64_t Obj_VrelLong_rms:5;
    uint64_t Obj_DistLat_rms2:2;
    uint64_t Obj_ArelLong_rms1:4;
    uint64_t Obj_VrelLat_rms2:4;
    uint64_t Obj_Orientation_rms1:2;
    uint64_t Obj_ArelLat_rms:5;
    uint64_t Obj_ArelLong_rms2:1;
    uint64_t Reserved1:5;
    uint64_t Obj_Orientation_rms2:3;
    uint64_t Reserved2:2;
    uint64_t Obj_MeasState:3;
    uint64_t Obj_ProbOfExist:3;
  } data = {};
  uint8_t raw_data[8];
} object_2_quality;
}
  • 定义 Object_2_Quality 类
namespace object_list {
class Object_2_Quality {
 public:
  Object_2_Quality();
  ~Object_2_Quality();
  int get_object_id();
  double get_object_long_dist_rms();	//获取Longitudinal(x)坐标标准差	单位:m
  double get_object_long_rel_vel_rms();	//获取 x 方向的相对速度的标准差		单位:m/s
  double get_object_lat_dist_rms();		//获取Lateral(y)坐标标准差		单位:m
  double get_object_lat_rel_vel_rms();	//获取 y 方向的相对速度的标准差	单位:m/s
  double get_object_long_rel_accel_rms();	//获取 x 方向的相对加速度的标准差	单位:m/s2
  double get_object_lat_rel_accel_rms();	//获取 y 方向的相对加速度的标准差	单位:m/s2
  double get_object_orientation_rms();	//获取方位角标准差	单位:deg
  int get_object_meas_state();	//测量状态:在新的测量周期内 object 是否有效,是否被 clusters 确认。0x0:deleted  0x1:new  0x2:measured  0x3: predicted  0x4:deleted for merge  0x5:new from merge
  int get_object_prob_of_exist();	//存在的概率。0x0:invalid  0x1:<25%  0x2:<50%  0x3:<75%  0x4:<90%  0x5:<99%  0x6:<99.9%  0x7:<=100%
  object_2_quality *get_object_2_quality();
 private:
  object_2_quality object_2_quality_msg;
  double signal_value_table[32] = {
      0.005, 0.006, 0.008, 0.011,
      0.014, 0.018, 0.023, 0.029,
      0.038, 0.049, 0.063, 0.081,
      0.105, 0.135, 0.174, 0.224,
      0.288, 0.371, 0.478, 0.616,
      0.794, 1.023, 1.317, 1.697,
      2.187, 2.817, 3.630, 4.676,
      6.025, 7.762, 10.000
  };	//Obj_Orientation_rms[deg]的信号值表
  double orientation_signal_value_table[32] = {
      0.005, 0.007, 0.010, 0.014,
      0.020, 0.029, 0.041, 0.058,
      0.082, 0.116, 0.165, 0.234,
      0.332, 0.471, 0.669, 0.949,
      1.346, 1.909, 2.709, 3.843,
      5.451, 7.734, 10.971, 15.565,
      22.081, 31.325, 44.439, 63.044,
      89.437, 126.881, 180.000
  };	//Obj_DistLong_rms, Obj_DistLat_rms [m] Obj_VrelLong_rms, Obj_VrelLat_rms [m/s] Obj_ArelLat_rms, Obj_ArelLong_rms [m/s2]信号值表
};
}
  • Object_2_Quality 类的实现
namespace object_list {
Object_2_Quality::Object_2_Quality() {
}
Object_2_Quality::~Object_2_Quality() {
}
int Object_2_Quality::get_object_id() {
  return static_cast<int>(object_2_quality_msg.data.Obj_ID);
}
double Object_2_Quality::get_object_lat_dist_rms() {
  return signal_value_table[static_cast<int>(object_2_quality_msg.data.Obj_DistLat_rms1 << 2 |
      object_2_quality_msg.data.Obj_DistLat_rms2)];
}	//存储位置从22-23位,8-10位。 <<2取的是高位部分(8-10位)数据,| rms2取的是剩下的2位(22-23位)数据
double Object_2_Quality::get_object_long_dist_rms() {
  return signal_value_table[static_cast<int>(object_2_quality_msg.data.Obj_DistLong_rms)];
}
double Object_2_Quality::get_object_lat_rel_vel_rms() {
  return signal_value_table[static_cast<int>(
      object_2_quality_msg.data.Obj_VrelLat_rms1 << 4
          | object_2_quality_msg.data.Obj_VrelLat_rms2)];
}	//存储位置从28-31位,16位。<<4取的是高位部分16位数据,| rms2取的是剩下的4位(28-32位)数据
double Object_2_Quality::get_object_long_rel_vel_rms() {
  return signal_value_table[static_cast<int>(object_2_quality_msg.data.Obj_VrelLong_rms)];
}
double Object_2_Quality::get_object_long_rel_accel_rms() {
  return signal_value_table[static_cast<int>(object_2_quality_msg.data.Obj_ArelLong_rms1 << 1 |
      object_2_quality_msg.data.Obj_ArelLong_rms2)];
}	//存储位置从39位,24-27位。<<1取的是高位部分(24-27位)数据,| rms2取的是剩下的低位(39位)的数据
double Object_2_Quality::get_object_lat_rel_accel_rms() {
  return signal_value_table[static_cast<int>(object_2_quality_msg.data.Obj_ArelLat_rms)];
}
int Object_2_Quality::get_object_meas_state() {
  return static_cast<int>(object_2_quality_msg.data.Obj_MeasState);
}
int Object_2_Quality::get_object_prob_of_exist() {
  return static_cast<int>(object_2_quality_msg.data.Obj_ProbOfExist);
}
double Object_2_Quality::get_object_orientation_rms() {
  return orientation_signal_value_table[
      static_cast<int>(object_2_quality_msg.data.Obj_Orientation_rms1 << 3 |
          object_2_quality_msg.data.Obj_Orientation_rms2)];
}	//存储位置从45-47位,32-33位。<<3取的是高位部分(32-33位)的数据,| rms2取的是剩下的低位(45-47位)的数据。
object_2_quality *Object_2_Quality::get_object_2_quality() {
  return &object_2_quality_msg;
}
}
5.4、Object extended information (0x60D)
  • 此消息包含 object 的扩展属性,并且仅当它在信号***RadarCfg_SendExtInfo*** (0x200) 中被激活时才会发送。它以与消息 Object_1_General (0x60B) 相同的方式为所有 objects 重复发送。

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

  • 定义用于存储数据的Union
namespace object_list {
typedef union object_3_extended {
  struct {
    uint64_t Object_ID:8;
    uint64_t Object_ArelLong1:8;
    uint64_t Object_ArelLat1:5;
    uint64_t Object_ArelLong2:3;
    uint64_t Object_Class:3;
    uint64_t Reserved:1;
    uint64_t Object_ArelLat2:4;
    uint64_t Object_OrientationAngle1:8;
    uint64_t Reserved2:6;
    uint64_t Object_OrientationAngle2:2;
    uint64_t Object_Length:8;
    uint64_t Object_Width:8;
  } data = {};
  uint8_t raw_data[8];
} object_3_extended;
}
  • 定义 Object_3_Extended 类
namespace object_list {
class Object_3_Extended {
 public:
  Object_3_Extended();
  ~Object_3_Extended();
  int get_object_id();
  double get_object_long_rel_accel();	//获取 x 方向的相对加速度  单位:m/s2
  double get_object_lat_rel_accel();	//获取 y 方向的相对加速度,该值恒置为0  单位:m/s2
  int get_object_class();		//获取目标类别,0x0:point  0x1:car  0x2:truck  0x3:not in use  0x4:motorcycle  0x5:bicycle  0x6:wide  0x7:reserved
  double get_object_orientation_angle();	//获取object的方位角。随着时间的推移,被追踪的障碍物的旋转运动所产生的角度变化。这个值的创建总是从“0”开始,并随着障碍物的旋转而增加。如果没有发生旋转,它将保持“0”。	单位:deg
  double get_object_length();	//获取被跟踪object的长度	单位:m
  double get_object_width();	//获取被跟踪object的宽度	单位:m
  object_3_extended *get_object_3_extended();
 private:
  object_3_extended object_3_extended_msg;
};
}
  • Object_3_Extended 类的实现
namespace object_list {
Object_3_Extended::Object_3_Extended() {
}
Object_3_Extended::~Object_3_Extended() {
}
int Object_3_Extended::get_object_id() {
  return static_cast<int>(object_3_extended_msg.data.Object_ID);
}
double Object_3_Extended::get_object_long_rel_accel() {
  return (object_3_extended_msg.data.Object_ArelLong1 << 3 |
      object_3_extended_msg.data.Object_ArelLong2) * 0.01 - 10.0;
}	//存储位置从21-23位,8-15位。<<3取的是高位部分(8-15位)数据,| Long2取的是剩下的低位部分(21-23位)数据。Offset为 -10.0,Res为 0.01
double Object_3_Extended::get_object_lat_rel_accel() {
  return (object_3_extended_msg.data.Object_ArelLat1 << 4 |
      object_3_extended_msg.data.Object_ArelLat2) * 0.01 - 2.50;
}	//存储位置从28-31位,16-20位。<<4取的是高位部分(16-20位)数据,| Long2取的是剩下的低位部分(28-31位)数据。Offset为 -2.50,Res为 0.01
double Object_3_Extended::get_object_orientation_angle() {
  return (object_3_extended_msg.data.Object_OrientationAngle1 << 2 |
      object_3_extended_msg.data.Object_OrientationAngle2) * 0.4 - 180.0;
}	//存储位置从46-47位,32-39位。<<2取的是高位部分(32-39位)数据,| Long2取的是剩下的低位部分(46-47位)数据。Offset为 -180.00,Res为 0.4
int Object_3_Extended::get_object_class() {
  return static_cast<int>(object_3_extended_msg.data.Object_Class);
}
double Object_3_Extended::get_object_length() {
  return object_3_extended_msg.data.Object_Length * 0.2;
}	//Res为 0.2
double Object_3_Extended::get_object_width() {
  return object_3_extended_msg.data.Object_Width * 0.2;
}	//Res为 0.2
object_3_extended *Object_3_Extended::get_object_3_extended() {
  return &object_3_extended_msg;
}
}
5.5、Object collision detection warning (0x60E)
  • 此消息包含碰撞检测警告状态,仅当碰撞检测在消息 CollDetCfg (0 x400) 中被激活时发送。它以与消息 Object_1_General (0x60B) 相同的方式为所有 objects 重复发送。

在这里插入图片描述

在这里插入图片描述

6、利用SocketCAN接收数据并存储及协议解析
  • 之前已经提到过,ARS_408毫米波雷达利用CAN口进行数据传输。前一部分已经实现了利用SocketCAN类来接收CAN口的数据,这部分将会把从CAN口接收的数据交由各部分协议进行处理,完成两部分的拼接工作。

  • 创建ars_40X_can.hpp文件

    • 引入SocketCAN类以及各个协议的头文件
    • 由于后续的数据是根据CAN messages的类型进行选择处理的,因此还需要定义enum类型的can_messages变量
    • 定义封装Socket接口及雷达协议的接口类:ARS_40X_CAN
#ifndef ARS_40X_ARS_40X_HPP
#define ARS_40X_ARS_40X_HPP

#include <socket_can/socket_can.hpp>	//使用SocketCAN进行CAN总线通信

#include "ars_40X/cluster_list.hpp"		//解析雷达的cluster模式数据
#include "ars_40X/motion_input_signals.hpp"		//雷达的运动输入信号
#include "ars_40X/object_list.hpp"		//解析雷达的object模式数据
#include "ars_40X/radar_cfg.hpp"		//雷达配置信息
#include "ars_40X/radar_state.hpp"		//雷达状态信息

#include <cstdint>
#include <string>
#include <iostream>

namespace ars_40X {
typedef enum can_messages {		//参照传感器 CAN messages表(传感器ID为 0)
  RadarCfg = 0x200,
  RadarState = 0x201,
  FilterCfg = 0x202,
  FilterState_Header = 0x203,
  FilterState_Cfg = 0x204,
  CollDetCfg = 0x400,
  CollDetRegionCfg = 0x401,
  CollDetState = 0x408,
  CollDetRegionState = 0x402,
  SpeedInformation = 0x300,
  YawRateInformation = 0x301,
  Cluster_0_Status = 0x600,
  Cluster_1_General = 0x701,
  Cluster_2_Quality = 0x702,
  Object_0_Status = 0x60A,
  Object_1_General = 0x60B,
  Object_2_Quality = 0x60C,
  Object_3_Extended = 0x60D,
  Object_4_Warning = 0x60E,
  VersionID = 0x700,
  CollDetRelayCtrl = 0x8,
} can_messages;			

class ARS_40X_CAN {
 public:
  ARS_40X_CAN();
  ARS_40X_CAN(std::string port);	//用于接收传入的端口号,该端口号主要用于socket的初始化
  ~ARS_40X_CAN();
  virtual bool receive_radar_data();	//虚函数,用于继承使用的该类的对象进行重写使用
  virtual bool send_radar_data(uint32_t frame_id);	
  cluster_list::Cluster_0_Status *get_cluster_0_status();
  cluster_list::Cluster_1_General *get_cluster_1_general();
  cluster_list::Cluster_2_Quality *get_cluster_2_quality();
  motion_input_signals::SpeedInformation *get_speed_information();
  motion_input_signals::YawRateInformation *get_yaw_rate_information();
  object_list::Object_0_Status *get_object_0_status();
  object_list::Object_1_General *get_object_1_general();
  object_list::Object_2_Quality *get_object_2_quality();
  object_list::Object_3_Extended *get_object_3_extended();
  radar_state::RadarState *get_radar_state();
  radar_cfg::RadarCfg *get_radar_cfg();		//各部分协议的状态返回函数
  virtual void send_cluster_0_status() {};
  virtual void send_cluster_1_general() {};
  virtual void send_cluster_2_quality() {};
  virtual void send_object_0_status() {};
  virtual void send_object_1_general() {};
  virtual void send_object_2_quality() {};
  virtual void send_object_3_extended() {};
  virtual void send_radar_state() {};		//虚函数,用于各部分数据解析之后的发送操作
 private:
  socket_can::SocketCAN can_;		//构建SocketCAN类对象
  cluster_list::Cluster_0_Status cluster_0_status_;
  cluster_list::Cluster_1_General cluster_1_general_;
  cluster_list::Cluster_2_Quality cluster_2_quality_;
  motion_input_signals::SpeedInformation speed_information_;
  motion_input_signals::YawRateInformation yaw_rate_information_;
  object_list::Object_0_Status object_0_status_;
  object_list::Object_1_General object_1_general_;
  object_list::Object_2_Quality object_2_quality_;
  object_list::Object_3_Extended object_3_extended_;
  radar_state::RadarState radar_state_;
  radar_cfg::RadarCfg radar_cfg_;	//构建各部分协议的类对象
};
}
#endif //ARS_40X_ARS_40X_HPP
  • 接口类 ARS_40X_CAN的实现
#include "ars_40X/ars_40X_can.hpp"

namespace ars_40X {
ARS_40X_CAN::ARS_40X_CAN() :
    can_("can1") {		//默认构造函数,指定默认的CAN口设备
}
ARS_40X_CAN::ARS_40X_CAN(std::string port) :
    can_(port.c_str()) {	//带参构造函数,从函数调用出获取需要绑定的设备端口号
}
ARS_40X_CAN::~ARS_40X_CAN() {
}
bool ARS_40X_CAN::receive_radar_data() {
  uint32_t frame_id;
  uint8_t dlc;
  uint8_t data[8] = {0};	//定义用于接收CAN口数据的变量
  bool read_status = can_.read(&frame_id, &dlc, data);	//读取CAN口数据,并对读取状态进行判断
  if (!read_status) {
    return false;
  }
  switch (frame_id) {	//根据获取的数据的frame_id来对其CAN messages类型进行判断,并交由相应解析部分处理
    case RadarState:memcpy(radar_state_.get_radar_state()->raw_data, data, dlc);
      send_radar_state();	
      break;	//memcpy()为内存拷贝函数,表示将数据从data中拷贝dlc个字节到raw_data中。之后通过调用send()函数将数据解析后得到的结果发送出去

    case Cluster_0_Status:memcpy(cluster_0_status_.get_cluster_0_status()->raw_data, data, dlc);
      send_cluster_0_status();
      break;

    case Cluster_1_General:memcpy(cluster_1_general_.get_cluster_1_general()->raw_data, data, dlc);
      send_cluster_1_general();
      break;

    case Cluster_2_Quality:memcpy(cluster_2_quality_.get_cluster_2_quality()->raw_data, data, dlc);
      send_cluster_2_quality();
      break;

    case Object_0_Status:memcpy(object_0_status_.get_object_0_status()->raw_data, data, dlc);
      send_object_0_status();
      break;

    case Object_1_General:memcpy(object_1_general_.get_object_1_general()->raw_data, data, dlc);
      send_object_1_general();
      break;

    case Object_2_Quality:memcpy(object_2_quality_.get_object_2_quality()->raw_data, data, dlc);
      send_object_2_quality();
      break;

    case Object_3_Extended:memcpy(object_3_extended_.get_object_3_extended()->raw_data, data, dlc);
      send_object_3_extended();
      break;

    default: {
#if DEBUG
      printf("Unidentified Message: %d\n", frame_id);	//如果frame_id不属于以上CAN messages类型,则输出错误信息。
#endif
      break;
    }
  }
  return true;
}
bool ARS_40X_CAN::send_radar_data(uint32_t frame_id) {	//向雷达发送数据的函数
  switch (frame_id) {
    case RadarCfg:can_.write(frame_id, 8, radar_cfg_.get_radar_cfg()->raw_data);
      break;	//发送雷达配置信息
    case SpeedInformation:
      can_.write(frame_id,
                 2,
                 speed_information_.get_speed_information()->raw_data);
      break;	//发送雷达速度信息
    case YawRateInformation:
      can_.write(frame_id,
                 2,
                 yaw_rate_information_.get_yaw_rate_information()->raw_data);
      break;	//发送雷达角速度信息
#if DEBUG
      default: printf("Frame ID not supported\n");	//发送不符合要求信息时的错误输出
#endif
  }
  return true;
}
cluster_list::Cluster_0_Status *ARS_40X_CAN::get_cluster_0_status() {
  return &cluster_0_status_;	//返回类对象,便于函数调用
}
cluster_list::Cluster_1_General *ARS_40X_CAN::get_cluster_1_general() {
  return &cluster_1_general_;
}
cluster_list::Cluster_2_Quality *ARS_40X_CAN::get_cluster_2_quality() {
  return &cluster_2_quality_;
}
motion_input_signals::SpeedInformation *ARS_40X_CAN::get_speed_information() {
  return &speed_information_;
}
motion_input_signals::YawRateInformation *ARS_40X_CAN::get_yaw_rate_information() {
  return &yaw_rate_information_;
}
object_list::Object_0_Status *ARS_40X_CAN::get_object_0_status() {
  return &object_0_status_;
}
object_list::Object_1_General *ARS_40X_CAN::get_object_1_general() {
  return &object_1_general_;
}
object_list::Object_2_Quality *ARS_40X_CAN::get_object_2_quality() {
  return &object_2_quality_;
}
object_list::Object_3_Extended *ARS_40X_CAN::get_object_3_extended() {
  return &object_3_extended_;
}
radar_state::RadarState *ARS_40X_CAN::get_radar_state() {
  return &radar_state_;
}
radar_cfg::RadarCfg *ARS_40X_CAN::get_radar_cfg() {
  return &radar_cfg_;
}
}
参考:
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值