这应该是最后的一篇配适博文了(但愿),如果测试的效果不理想或者存在问题我会继续记录的。

这是一个之前工作的后续收尾,包括对xx_controller.cc中反馈检测(CheckResponse)的补充,也包括对技术文档内剩下的内容的实现。

目录

2020年12月23日星期三    1

对tsy_controller.cc的CheckResponse收尾    1

在0x10的电机反馈中添加的代码:    2

在制动0x142内添加的代码:    3

在转向0x401内添加的代码:    3

将反馈车速的单位调整为m/s    4

注册新车辆    5

 

 

 

2020年12月23日星期三

对tsy_controller.cc的CheckResponse收尾

添加`CheckResponse`逻辑,Apollo程序内增加了对车辆底层是否在自动驾驶模式的监控,即车辆横向、驱动、制动模块的驾驶模式反馈是否处于自动驾驶状态,如果在一个`CheckResponse`周期内,车辆某个模块驾驶模块反馈处于接管或者手动驾驶模式,则Apollo会控制车辆使能为紧急停车模式(`Emergency`),即各模块均控制为手动模式,确保控制车辆时的安全。不同的车辆`CheckResponse`周期可能不同,需要开发者根据情况通过设置`retry_num`设定`check`周期。

开发者可以不改原check代码方案,将3个驾驶模式反馈报文与apollo`chassis_detail`做映射:

 

`is_eps_online->转向模式反馈信号` 

 

`is_vcu_online->驱动模式反馈信号` 

 

`is_esp_online->制动模式反馈信号`

 

`apollo/modules/canbus/vehicle/ge3/protocol/scu_eps_311.cc`文件内,增加以下代码:

```

chassis->mutable_check_response()->set_is_eps_online(eps_drvmode(bytes, length) == 3);

```

`apollo/modules/canbus/vehicle/ge3/protocol/scu_vcu_1_312.cc`文件内,增加以下代码:

```

chassis->mutable_check_response()->set_is_vcu_online(vcu_drvmode(bytes, length) == 3);

```

`apollo/modules/canbus/vehicle/ge3/protocol/scu_bcs_1_306.cc`文件内,增加以下代码:

```

chassis->mutable_check_response()->set_is_esp_online(bcs_drvmode(bytes, length) == 3);

对黄色高亮部分的修改首先要确定是在哪三个文件中添加代码。经过我对ge3以及devkit代码的分析,发现应该加在转向/驱动/制动的反馈报文处,下面我贴出devkit在制动反馈报文中的代码:

文件名称为break_report_501.cc。

void Brakereport501::Parse(const std::uint8_t* bytes, int32_t length,

                           ChassisDetail* chassis) const {

  chassis->mutable_devkit()->mutable_brake_report_501()->set_brake_pedal_actual(

      brake_pedal_actual(bytes, length));

  chassis->mutable_devkit()->mutable_brake_report_501()->set_brake_flt2(

      brake_flt2(bytes, length));

  chassis->mutable_devkit()->mutable_brake_report_501()->set_brake_flt1(

      brake_flt1(bytes, length));

  chassis->mutable_devkit()->mutable_brake_report_501()->set_brake_en_state(

      brake_en_state(bytes, length));

  chassis->mutable_check_response()->set_is_esp_online(

      brake_en_state(bytes, length) == 1);

}

所以我们也要加在反馈报文处,按道理我们应该加在几个控制器的反馈信号报文内,即:转向在0x401,驱动在0x10/20/30/40,制动在0x142。我认为我应该修改tsy_message_menager.cc中的report报文,将这几个信号的注释给去掉,将他们加入chassis().tsy()这个结构下。

在0x10的电机反馈中添加的代码:

为什么ge3中是==3,而devkit是==1呢?因为那是他们自己定义的正常状态,我们没有一个使能的反馈,只好用错误码当做反馈使用了,错误码的正常状态就是0。

  1. void Mcufltorquefeedback10::Parse(const std::uint8_t* bytes, int32_t length,  
  2.                          ChassisDetail* chassis) const {  
  3.   chassis->mutable_tsy()->mutable_mcufl_torque_feedback_10()->set_fl_errorcode(fl_errorcode(bytes, length));  
  4.   chassis->mutable_tsy()->mutable_mcufl_torque_feedback_10()->set_fl_motortemp(fl_motortemp(bytes, length));  
  5.   chassis->mutable_tsy()->mutable_mcufl_torque_feedback_10()->set_fl_current(fl_current(bytes, length));  
  6.   chassis->mutable_tsy()->mutable_mcufl_torque_feedback_10()->set_fl_torque(fl_torque(bytes, length));  
  7.   chassis->mutable_tsy()->mutable_mcufl_torque_feedback_10()->set_fl_speed(fl_speed(bytes, length));  
  8.   chassis->mutable_tsy()->mutable_mcufl_torque_feedback_10()->set_fl_shift(fl_shift(bytes, length));  
  9.   //tsy_controller.ccCheckReponse中要求的代码  
  10.   chassis->mutable_check_response()->set_is_vcu_online(  
  11.       fl_errorcode(bytes, length) == 0);  
  12. }  

在制动0x142内添加的代码:

  1. void Dbsfstatus142::Parse(const std::uint8_t* bytes, int32_t length,  
  2.                          ChassisDetail* chassis) const {  
  3.   chassis->mutable_tsy()->mutable_dbsf_status_142()->set_dbsf_reserved_2(dbsf_reserved_2(bytes, length));  
  4.   chassis->mutable_tsy()->mutable_dbsf_status_142()->set_dbsf_fault_code(dbsf_fault_code(bytes, length));  
  5.   chassis->mutable_tsy()->mutable_dbsf_status_142()->set_dbsf_hp_pressure(dbsf_hp_pressure(bytes, length));  
  6.   chassis->mutable_tsy()->mutable_dbsf_status_142()->set_dbsf_reserved_1(dbsf_reserved_1(bytes, length));  
  7.   chassis->mutable_tsy()->mutable_dbsf_status_142()->set_dbsf_system_status(dbsf_system_status(bytes, length));  
  8.   //tsy_controller.ccCheckReponse中要求的代码  
  9.   chassis->mutable_check_response()->set_is_esp_online(  
  10.       dbsf_fault_code(bytes, length) == 0);  
  11. }  

在转向0x401内添加的代码:

但是这里需要注意,转向电机并没有错误码的反馈,或许抑或校验值可以判断,但是我选择了转向电机的工作模式来判断,当模式为0x20,也就是十进制下的32的时候,电机为角度控制模式,也就是说发送角度请求是可以获得响应的。

  1. void Epsfstatus401::Parse(const std::uint8_t* bytes, int32_t length,  
  2.                          ChassisDetail* chassis) const {  
  3.   chassis->mutable_tsy()->mutable_epsf_status_401()->set_epsf_check_sum(epsf_check_sum(bytes, length));  
  4.   chassis->mutable_tsy()->mutable_epsf_status_401()->set_epsf_reserved2(epsf_reserved2(bytes, length));  
  5.   chassis->mutable_tsy()->mutable_epsf_status_401()->set_epsf_angle_in_middle_calib(epsf_angle_in_middle_calib(bytes, length));  
  6.   chassis->mutable_tsy()->mutable_epsf_status_401()->set_low_epsf_angle(low_epsf_angle(bytes, length));  
  7.   chassis->mutable_tsy()->mutable_epsf_status_401()->set_high_epsf_angle(high_epsf_angle(bytes, length));  
  8.   chassis->mutable_tsy()->mutable_epsf_status_401()->set_epsf_reserved1(epsf_reserved1(bytes, length));  
  9.   chassis->mutable_tsy()->mutable_epsf_status_401()->set_epsf_steering_wheel_torque_value(epsf_steering_wheel_torque_value(bytes, length));  
  10.   chassis->mutable_tsy()->mutable_epsf_status_401()->set_epsf_work_mode_status(epsf_work_mode_status(bytes, length));  
  11.   //tsy_controller.ccCheckReponse中要求的代码  
  12.   chassis->mutable_check_response()->set_is_eps_online(  
  13.       epsf_work_mode_status(bytes, length) != 32);  
  14. }  

将反馈车速的单位调整为m/s

下面是技术文档中的参考内容:

### 4.修改底盘车速反馈协议,将车速反馈单位由km/h转化为m/s

Apollo系统内默认使用车速反馈量为`m/s`,底盘车速信息对Apollo非常重要,在车辆标定、控制、规划等都需要采集该数据,所以开发者要在开发适配代码时,重点检查车速反馈的单位。车速由`km/h`转化为`m/s`时,在反馈车速的信号除以`3.6`即可。

找到Ge3车辆反馈车速的报文在文件`apollo/modules/canbus/vehicle/ge3/protocol/scu_bcs_2_307.cc` 下,反馈车速消息为`Scubcs2307::bcs_vehspd{}`

我们这辆车的车速反馈报文整合在了0x304的信号里:

所以我们在modules/canbus/vehicle/tsy/protocol/vcu_vehicle_status_2_304.cc里面,找到反馈消息Vcuvehiclestatus2304::vehicle_speed{},进行下面的修改:

  1. // config detail: {'bit': 0, 'is_signed_var': False, 'len': 16, 'name': 'vehicle_speed', 'offset': -80.0, 'order': 'intel', 'physical_range': '[-80|80]', 'physical_unit': 'km/h', 'precision': 0.1, 'type': 'double'}  
  2. double Vcuvehiclestatus2304::vehicle_speed(const std::uint8_t* bytes, int32_t length) const {  
  3.   Byte t0(bytes + 1);  
  4.   int32_t x = t0.get_byte(0, 8);  
  5.     
  6.   Byte t1(bytes + 0);  
  7.   int32_t t = t1.get_byte(0, 8);  
  8.   x <<= 8;  
  9.   x |= t;  
  10.     
  11.   double ret = (x * 0.100000 + -80.000000)/3.6;  
  12.   return ret;  
  13. }  

注册新车辆

参考技术文档内的内容进行注册车辆。

### 5.注册新车辆

`modules/canbus/vehicle/vehicle_factory.cc`里注册新的车辆,在该文件内新建如下类:

![register_ge3](images/vehicle_adaption_tutorial/register_ge3.png)

添加头文件

![add_head_file](images/vehicle_adaption_tutorial/add_head_file.png)

添加BUILD依赖库

`apollo/modules/canbus/vehicle/BUILD` 文件内添加`ge3_vehicle_factory`依赖库。

![add_build_depend](images/vehicle_adaption_tutorial/add_build_depend.png)

下面代码在文件modules/canbus/vehicle/vehicle_factory.cc里添加:

  1. //注册tsy的车辆工厂  
  2. Register(apollo::common::TSY, []() -> AbstractVehicleFactory * {  
  3.   return new TsyVehicleFactory();  
  4. }); 
  5. //添加tsy的车辆工厂头文件  
  6. #include "modules/canbus/vehicle/tsy/tsy_vehicle_factory.h"  

下面代码在文件apollo/modules/canbus/vehicle/BUILD里添加:

  1. cc_library(  
  2.     name = "vehicle_factory",  
  3.     srcs = ["vehicle_factory.cc"],  
  4.     hdrs = ["vehicle_factory.h"],  
  5.     copts = CANBUS_COPTS,  
  6.     deps = [  
  7.         ":abstract_vehicle_factory",  
  8.         "//modules/canbus/vehicle/ch:ch_vehicle_factory",  
  9.         "//modules/canbus/vehicle/devkit:devkit_vehicle_factory",  
  10.         "//modules/canbus/vehicle/ge3:ge3_vehicle_factory",  
  11.         "//modules/canbus/vehicle/gem:gem_vehicle_factory",  
  12.         "//modules/canbus/vehicle/lexus:lexus_vehicle_factory",  
  13.         "//modules/canbus/vehicle/lincoln:lincoln_vehicle_factory",  
  14.         "//modules/canbus/vehicle/neolix_edu:neolix_edu_vehicle_factory",  
  15.         "//modules/canbus/vehicle/transit:transit_vehicle_factory",  
  16.         "//modules/canbus/vehicle/wey:wey_vehicle_factory",  
  17.         "//modules/canbus/vehicle/zhongyun:zhongyun_vehicle_factory",  
  18.         "//modules/common/util:factory",  
  19.         #下面是tsy的车辆工厂依赖文件  
  20.         "//modules/canbus/vehicle/tsy:tsy_vehicle_factory",  
  21.     ],  
  22. )  

更新配置文件

参考技术文档的内容更新配置文件。

### 6.更新配置文件

`modules/canbus/proto/vehicle_parameter.proto` 文件内添加GE3车辆分支。

![register1_ge3](images/vehicle_adaption_tutorial/register1_ge3.png)

`modules/canbus/conf/canbus_conf.pb.txt` 更新配置,改为ge3canbus通信程序。

![register2_ge3](images/vehicle_adaption_tutorial/register2_ge3.png)

先在proto文件里添加TSY车辆分支,但是发现没有emun的内容,所以参考一下袁珺博士的南阳理工学院的配适文件:

message VehicleParameter {

  enum VehicleBrand {

    LINCOLN_MKZ = 0;

    GEM = 1;

    CH = 2;

    AGILEX = 4;

    AGRIBOT = 5;

    NYLG = 6;

  }

 

  optional VehicleBrand brand = 1;

  optional double max_engine_pedal = 2;

  optional int32 max_enable_fail_attempt = 3;

  optional Chassis.DrivingMode driving_mode = 4;

}

下面是参考后我们的代码:

  1. message VehicleParameter {  
  2.   enum VehicleBrand {  
  3.     LINCOLN_MKZ = 0;  
  4.     GEM = 1;  
  5.     CH = 2;  
  6.     AGILEX = 4;  
  7.     AGRIBOT = 5;  
  8.     TSY = 6;  
  9.   }  
  10.       
  11.   optional apollo.common.VehicleBrand brand = 1;  
  12.   optional double max_engine_pedal = 2;  
  13.   optional int32 max_enable_fail_attempt = 3;  
  14.   optional Chassis.DrivingMode driving_mode = 4;  
  15. }  

然后在conf文件中更改通信方式:

  1. vehicle_parameter {  
  2.   brand: TSY  
  3.   max_enable_fail_attempt: 5  
  4.   driving_mode: COMPLETE_AUTO_DRIVE  
  5. }  
  6.     
  7. can_card_parameter {  
  8.   brand: SOCKET_CAN_RAW  
  9.   type: PCI_CARD  
  10.   channel_id: CHANNEL_ID_ZERO  
  11.   interface: NATIVE  
  12. }  
  13.     
  14. enable_debug_mode: false  
  15. enable_receiver_log: false  
  16. enable_sender_log: false 

vehicle的brand在上面调的那个文件里可以看到:modules/canbus/proto/vehicle_parameter.proto。can_card的brand可以在这个文件里看到:apollo\modules\drivers\canbus\proto\can_card_parameter.proto。

 

到这里收尾结束,底层CAN通讯和车辆配适的工作算是告一段落了。剩下的应该是对DBC配适的检测了,检测方法在技术文档中也提到了,使用teleop工具来检测。

 

本篇完

2020年12月23日 15:23

于宁波天尚元振狮路365号工厂二楼