我是菜逼,本篇的"第三次尝试"后面的内容感谢自动驾驶社区浩哥的大力支持。

本篇接续上一篇的配适工作,希望可以build通过,主要是使用teleop工具联调需要先build才能让代码生效。

写在前面:SB Apollo6.0 下面提到的问题在Apollo 2.5上是不存在的,可是我还是希望使用cyber RT,所以我要版本回滚3.5了。

这篇文章是来记录配适之后存在的各种问题,以及解决方法,希望可以在20年底之前把这部分工作做完。、

整篇文章的解决问题的方法基本上是遵循控制变量法的,所以可能会有些啰嗦。

2020年12月24日星期四

Build 问题

按照技术文档进行操作后,在Apollo docker中输入指令sudo bash apollo.sh build来执行build指令。

Proto报错

Tsy is not defined,原因是在chassis_detail.proto中的import …/tsy.proto这句话出错了,给出的错误是was not found or had errors。

第一次尝试

我不知道这个原因是什么,因为看下面图片中的内容,可以看到是有这个tsy.proto的,并且路径也没有问题,import的路径也没有问题,所以初步判断是这个proto文件有问题。

我向南阳理工学院的袁珺博士请教,他说他们的车配适完成了,尽管他们是基于Apollo2.0的,内核不是cyber RT,而是ROS。但是我想这一点应该是一致的,所以我去查看他提供的文件,因为他的报文数量很少,所以在nylg.proto中的结构很明了。我打算按照nylg.proto以及Apollo提供的devkit.proto的内容来重写tsy.proto,希望可以找到问题。

因为我的报文过多,很多是不需要的,所以我需要根据tsy_message_menager.cc中的定义来规定具体包括哪些内容。

注意需要重新给最后面message Tsy{…}中的信号重新编号。

这是tsy.proto的内容。

这是tsy_message_menager.cc的内容。

在做这样的工作的时候,我发现了一些问题,为什么我DBC转换后的一些报文名称出现了问题?比如说上图最后一行的EPB_status_375,他的最后怎么会出现两次375呢?然后这在我之前自动生成的tsy.proto中也发现了类似的错误:

所以我希望是这里的原因,因此我在新的tsy_new1.proto中没有这样的报文了,用这样的tsy.proto再去工控机上build一次。

结果依旧是这个错误。

第二次尝试

将这个问题的错误反馈到百度里搜索,很多都是说protobuf版本不对的问题。我查看了手头工控机的protoc的版本,是3.0.0的,可是里面的proto文件开头都是proto2,感觉并不存在版本不对的问题。

但是因为这个不知道是什么原因,我将开头的proto2改为了proto3,再次build。

结果依旧错误,反而这样子错误更多了,看来方向不太对。

第三次尝试

可以给大家一点我尝试的方向,或许对于这个报错是个参考,包括绝对路径和相对路径的更改,包括package的问题。

好了,我放弃了,查了很多资料,找了很多大佬,没有找到可以解决这个问题的方案,我认为这就是崔工所说的bug,折磨了我快一天了,从昨天下午4点到现在。到此结束吧,我要版本回滚知Apollo3.5了,下一篇就不会是基于6.0的文章了,SB Apollo6.0.

上面的话作废,我是菜逼。

 

本篇完

2020年12月24日 18:08

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

 

第四次尝试

在浩哥的大力协助下,找到了这个问题,应该在同文件夹下的BUILD中找到chassis_detail的library,在依赖项deps中添加tsy的相关文件,如下所示

首先先完善tsy的BUILD部分,下面是添加代码:

  1. proto_library(  
  2.     name = "tsy_proto",  
  3.     srcs = ["tsy.proto"],  
  4. )  
  5. ##参考技术文档并没有找到合适的proto_library叫做canbus_proto_lib  
  6.     
  7. cc_proto_library(  
  8.     name = "tsy_cc_proto",  
  9.     deps = [  
  10.         ":tsy_proto",  
  11.     ],  
  12. )  
  13.     
  14. py_proto_library(  
  15.     name = "tsy_py_pb2",  
  16.     deps = [  
  17.         ":tsy_proto",  
  18.     ],  
  19. )  

再完善chassis_detail的BUILD部分,黄色的是添加代码:

  1. proto_library(  
  2.     name = "chassis_detail_proto",  
  3.     srcs = ["chassis_detail.proto"],  
  4.     deps = [  
  5.         ":ch_proto",  
  6.         ":chassis_proto",  
  7.         ":devkit_proto",  
  8.         ":ge3_proto",  
  9.         ":lexus_proto",  
  10.         ":neolix_edu_proto",  
  11.         ":transit_proto",  
  12.         ":wey_proto",  
  13.         ":zhongyun_proto",  
  14.         ##就这个SB地方没加这句话,让我被折磨了一天  
  15.         ":tsy_proto",  
  16.         "//modules/common/configs/proto:vehicle_config_proto",  
  17.     ],  
  18. )  
  19.     
  20. py_proto_library(  
  21.     name = "chassis_detail_py_pb2",  
  22.     deps = [  
  23.         ":ch_py_pb2",  
  24.         ":chassis_detail_proto",  
  25.         ":chassis_py_pb2",  
  26.         ":devkit_py_pb2",  
  27.         ":ge3_py_pb2",  
  28.         ":lexus_py_pb2",  
  29.         ":neolix_edu_py_pb2",  
  30.         ":transit_py_pb2",  
  31.         ":wey_py_pb2",  
  32.         ":zhongyun_py_pb2",  
  33.         ##就这个SB地方没加这句话,让我被折磨了一天  
  34.         ":tsy_py_pb2",  
  35.         "//modules/common/configs/proto:vehicle_config_py_pb2",  
  36.     ],  
  37. )  

Protocol报错

删除在tsy.proto中没有引用或者定义的报文.cc/.h文件,只有在tsy.proto中添加了的文件才能被canbus/vehicle/tsy/protocol/BUILD里面的*.cc和*.h所使用,不然会报错,类似这样:

第一张图是没有在proto中的最后面没有定义这个报文。

第二张图是proto中根本没有使用到的。

Time.h报错

报错的界面如下图:

这个问题是来自于之前使用的工具,他是基于以前版本的Apollo来生成的代码,那个时候还是ROS,现在time.h已经再cyber中被定义了,可以查看devkit_controller.cc的代码:

#include "modules/canbus/vehicle/devkit/devkit_controller.h"

 

#include "cyber/common/log.h"

#include "cyber/time/time.h"

#include "modules/canbus/vehicle/devkit/devkit_message_manager.h"

#include "modules/canbus/vehicle/vehicle_controller.h"

#include "modules/common/proto/vehicle_signal.pb.h"

#include "modules/drivers/canbus/can_comm/can_sender.h"

#include "modules/drivers/canbus/can_comm/protocol_data.h"

所以我们对tsy_controller.cc中的头文件进行修改:

  1. #include "modules/canbus/vehicle/devkit/devkit_controller.h"  
  2.     
  3. #include "cyber/common/log.h"  
  4. #include "cyber/time/time.h"  
  5. #include "modules/canbus/vehicle/devkit/devkit_message_manager.h"  
  6. #include "modules/canbus/vehicle/vehicle_controller.h"  
  7. #include "modules/common/proto/vehicle_signal.pb.h"  
  8. #include "modules/drivers/canbus/can_comm/can_sender.h"  
  9. #include "modules/drivers/canbus/can_comm/protocol_data.h"  

Tsy_message_maneger.cc报错

这个错误一目了然,是原来的遗留问题。当我在modules/canbus/vehicle/tsy/protocol/文件夹下删除了不需要的.cc和.h文件后,原本存在于一些文件中对他们的引用也就不支持了,所以会报错,错误如下图:

所以在tsy_message_maneger.cc中删除多余的.h文件的include就好了:

  1. #include "modules/canbus/vehicle/tsy/tsy_message_manager.h"  
  2.     
  3. #include "modules/canbus/vehicle/tsy/protocol/iecu_control_distributed_505.h"  
  4. #include "modules/canbus/vehicle/tsy/protocol/iecu_control_flag_501.h"  
  5. #include "modules/canbus/vehicle/tsy/protocol/iecu_control_ibc_503.h"  
  6. #include "modules/canbus/vehicle/tsy/protocol/iecu_control_power_504.h"  
  7. #include "modules/canbus/vehicle/tsy/protocol/iecu_control_steering_502.h"  
  8.     
  9. #include "modules/canbus/vehicle/tsy/protocol/dbsf_status_142.h"  
  10. //#include "modules/canbus/vehicle/tsy/protocol/epb_status_375_375.h"  
  11. #include "modules/canbus/vehicle/tsy/protocol/epsf_status_401.h"  
  12. //#include "modules/canbus/vehicle/tsy/protocol/epsr_status_111.h"  
  13. //#include "modules/canbus/vehicle/tsy/protocol/imu_acceleration_181.h"  
  14. //#include "modules/canbus/vehicle/tsy/protocol/imu_angular_281.h"  
  15. //#include "modules/canbus/vehicle/tsy/protocol/imu_euler_381.h"  
  16. #include "modules/canbus/vehicle/tsy/protocol/mcufl_drive_motor_feedback_msg_60.h"  
  17. #include "modules/canbus/vehicle/tsy/protocol/mcufl_torque_feedback_10.h"  
  18. #include "modules/canbus/vehicle/tsy/protocol/mcufr_drive_motor_feedback_msg_70.h"  
  19. #include "modules/canbus/vehicle/tsy/protocol/mcufr_torque_feedback_20.h"  
  20. #include "modules/canbus/vehicle/tsy/protocol/mcurl_drive_motor_feedback_msg_80.h"  
  21. #include "modules/canbus/vehicle/tsy/protocol/mcurl_torque_feedback_30.h"  
  22. #include "modules/canbus/vehicle/tsy/protocol/mcurr_drive_motor_feedback_msg_90.h"  
  23. #include "modules/canbus/vehicle/tsy/protocol/mcurr_torque_feedback_40.h"  
  24. /* 
  25. #include "modules/canbus/vehicle/tsy/protocol/remote_control_io_10a.h" 
  26. #include "modules/canbus/vehicle/tsy/protocol/remote_control_shake_2_10b.h" 
  27. #include "modules/canbus/vehicle/tsy/protocol/vcu_dbsf_request_154.h" 
  28. #include "modules/canbus/vehicle/tsy/protocol/vcu_epb_request_310_310.h" 
  29. #include "modules/canbus/vehicle/tsy/protocol/vcu_epsf_control_request_469.h" 
  30. #include "modules/canbus/vehicle/tsy/protocol/vcu_epsr_control_request_101.h" 
  31. #include "modules/canbus/vehicle/tsy/protocol/vcu_mcufl_request_1_160.h" 
  32. #include "modules/canbus/vehicle/tsy/protocol/vcu_mcufr_request_1_170.h" 
  33. #include "modules/canbus/vehicle/tsy/protocol/vcu_mcurl_request_1_180.h" 
  34. #include "modules/canbus/vehicle/tsy/protocol/vcu_mcurr_request_1_190.h" 
  35. */  
  36. #include "modules/canbus/vehicle/tsy/protocol/vcu_vehicle_diagnosis_301.h"  
  37. #include "modules/canbus/vehicle/tsy/protocol/vcu_vehicle_status_1_303.h"  
  38. #include "modules/canbus/vehicle/tsy/protocol/vcu_vehicle_status_2_304.h"  
  39. #include "modules/canbus/vehicle/tsy/protocol/vcu_vehicle_status_3_305.h"  
  40. //#include "modules/canbus/vehicle/tsy/protocol/vector__independent_sig_msg_c0000000.h"  

TSY is not a member of 'apollo::common'

这个问题以前碰到过,应该是在common下面的一个文件里要添加TSY。

先看一下报错界面:

需要修改的文件路径是apollo/modules/common/configs/proto/vehicle_config.proto,需要添加的代码如下:

  1. enum VehicleBrand {  
  2.   LINCOLN_MKZ = 0;  
  3.   GEM = 1;  
  4.   LEXUS = 2;  
  5.   TRANSIT = 3;  
  6.   GE3 = 4;  
  7.   WEY = 5;  
  8.   ZHONGYUN = 6;  
  9.   CH = 7;  
  10.   DKIT = 8;  
  11.   NEOLIX = 9;  
  12.   //需要注册车辆品牌vehicle brand  
  13.   TSY = 10;  
  14. }  

TSY was not declared in this scope报错(多个错误,下面细说)

报错界面:

这部分的错误比较多,挨个分析并解决吧,不过主要还是集中在tsy_controller.cc中。

第一处错误:expected primary-expression before '.' token

这个问题,网上比较有代表性的博客是这一篇:https://www.cnblogs.com/MartinLwx/p/12533140.html ,给出的原因是错误的原因是:把类型(type)当成变量来用了(variable)

所以我决定去掉原来程序中的:

TSY tsy = chassis_detail.tsy();

而是把tsy_controller.cc中所有的tsy都用chassis_detail.tsy()替代

第二处错误:'class apollo::canbus::tsy::Iecucontrolibc503' has no member named 'set_iecu_breakpressure_cmd'; did you mean 'set_iecu_brakepressure_cmd'?

这个错误看样子是我名字打错了,我需要检查一下,需要检查的应该包括modules/canbus/vehicle/tsy/protocol/中的一些.cc/.h文件。

先记录一下,刹车是brake,不是break,虽然发音都一样,但是意思不太一样,是我SB了。

这里我也是用错名字了,在0x504.h中可以看到规定的是这个对象:

诸如此类的错误不再举例了,统称为SB错误,我先改完再看还有没有其他错误。

第三处错误:'class apollo::canbus::VehicleParameter' has no member named 'max_steer_angle_spd'

如图:

我记得在这段代码的其他部分有着类似的定义,我需要去devkit_controller.cc中找一下他们引用的文件路径,去那个文件中添加一下。

看来是这样子理解的:这个是proto中生成的namespace,是以package apollo.canbus为开头,在后面有meassage VehicleParameter{…}的设置,在这个message中规定的内容就会算在apollo::canbus:: VehicleParameter的命名空间里,如果是not a member或者no member named xx,表示没有在里面定义。

第四处错误:ProtocolData::BoundedValue报错

错误如图:

这段错误的意思是我没有对ProtocolData指定模板参数(template parameters),这样的话我需要先找到ProtocolData这个类定义的位置,在Vscode中,按住ctrl,左键点击ProtocolData,就会跳转到一个头文件:/home/l/apollo/modules/drivers/canbus/can_comm/protocol_data.h,在这里这里定义了命名空间下namespace apollo::drivers::canbus的类ProtocolData,其中包括这个函数BoundedValue。让我们看一下函数内容,其实就是实现了一个不要越界发指令的问题,但是在开头规定了需要制定模板类型,同样这个函数也要求指定模板类型T,所以我在tsy_controller.cc中的ProtocolData后面指定一下参数类型就好了。

代码添加这个黄色高亮部分就可以了,因为转角速度是double类型的。

  1. // steering with new angle speed  
  2. // angle:-99.99~0.00~99.99, unit:, left:-, right:+  
  3. // angle_spd:0.00~99.99, unit:deg/s  
  4. void TsyController::Steer(double angle, double angle_spd) {  
  5.   if (driving_mode() != Chassis::COMPLETE_AUTO_DRIVE &&  
  6.       driving_mode() != Chassis::AUTO_STEER_ONLY) {  
  7.     AINFO << "The current driving mode does not need to set steer.";  
  8.     return;  
  9.   }  
  10.   const double real_angle = params_.max_steer_angle() * angle / 100.0;  
  11.   const double real_angle_spd = ProtocolData<double> ::BoundedValue(  
  12.       params_.min_steer_angle_spd(), params_.max_steer_angle_spd(),  
  13.       params_.max_steer_angle_spd() * angle_spd / 100.0);  
  14.   // reverse sign  
  15.   iecu_control_steering_502_->set_iecu_ftire_angle_cmd(real_angle);  
  16.   iecu_control_steering_502_->set_iecu_ftire_speed_cmd(real_angle_spd);  
  17. }  

第五处错误:'absl' has not been declared

这是一个很经典的问题了,也是因为自动生成的代码并非Apollo6.0最新支持的,这是老版本的使用方法,新版本参考devkit_controller.cc修改一下就好了。

PS:[这里需要指出的是,absl是谷歌自动生成的库,平时是看不到的]

比如说start这个问题,先看一下devkit的代码:

  std::chrono::duration<double, std::micro> default_period{50000};

  int64_t start = 0;

  int64_t end = 0;

  while (can_sender_->IsRunning()) {

    start = ::apollo::cyber::Time::Now().ToMicrosecond();

    const Chassis::DrivingMode mode = driving_mode();

    bool emergency_mode = false;

 

那么我们的代码是长这个样子的:

  std::chrono::duration<double, std::micro> default_period{50000};

  int64_t start = 0;

  int64_t end = 0;

  while (can_sender_->IsRunning()) {

    start = absl::ToUnixMicros(::apollo::common::time::Clock::Now());

    const Chassis::DrivingMode mode = driving_mode();

    bool emergency_mode = false;

其他的absl使用也是一样的问题,他们都在SecurityDogThreadFunc()这个函数里,我们直接复制粘贴就好了,修改后的代码我都贴在下面:

  1. void TsyController::SecurityDogThreadFunc() {  
  2.   int32_t vertical_ctrl_fail = 0;  
  3.   int32_t horizontal_ctrl_fail = 0;  
  4.     
  5.   if (can_sender_ == nullptr) {  
  6.     AERROR << "Failed to run SecurityDogThreadFunc() because can_sender_ is "  
  7.               "nullptr.";  
  8.     return;  
  9.   }  
  10.   while (!can_sender_->IsRunning()) {  
  11.     std::this_thread::yield();  
  12.   }  
  13.     
  14.   std::chrono::duration<double, std::micro> default_period{50000};  
  15.   int64_t start = 0;  
  16.   int64_t end = 0;  
  17.   while (can_sender_->IsRunning()) {  
  18.     start = ::apollo::cyber::Time::Now().ToMicrosecond();  
  19.     const Chassis::DrivingMode mode = driving_mode();  
  20.     bool emergency_mode = false;  
  21.     
  22.     // 1. horizontal control check  
  23.     if ((mode == Chassis::COMPLETE_AUTO_DRIVE ||  
  24.          mode == Chassis::AUTO_STEER_ONLY) &&  
  25.         CheckResponse(CHECK_RESPONSE_STEER_UNIT_FLAG, false) == false) {  
  26.       ++horizontal_ctrl_fail;  
  27.       if (horizontal_ctrl_fail >= kMaxFailAttempt) {  
  28.         emergency_mode = true;  
  29.         set_chassis_error_code(Chassis::MANUAL_INTERVENTION);  
  30.       }  
  31.     } else {  
  32.       horizontal_ctrl_fail = 0;  
  33.     }  
  34.     
  35.     // 2. vertical control check  
  36.     if ((mode == Chassis::COMPLETE_AUTO_DRIVE ||  
  37.          mode == Chassis::AUTO_SPEED_ONLY) &&  
  38.         !CheckResponse(CHECK_RESPONSE_SPEED_UNIT_FLAG, false)) {  
  39.       ++vertical_ctrl_fail;  
  40.       if (vertical_ctrl_fail >= kMaxFailAttempt) {  
  41.         emergency_mode = true;  
  42.         set_chassis_error_code(Chassis::MANUAL_INTERVENTION);  
  43.       }  
  44.     } else {  
  45.       vertical_ctrl_fail = 0;  
  46.     }  
  47.     if (CheckChassisError()) {  
  48.       set_chassis_error_code(Chassis::CHASSIS_ERROR);  
  49.       emergency_mode = true;  
  50.     }  
  51.     
  52.     if (emergency_mode && mode != Chassis::EMERGENCY_MODE) {  
  53.       set_driving_mode(Chassis::EMERGENCY_MODE);  
  54.       message_manager_->ResetSendMessages();  
  55.     }  
  56.     end = ::apollo::cyber::Time::Now().ToMicrosecond();  
  57.     std::chrono::duration<double, std::micro> elapsed{end - start};  
  58.     if (elapsed < default_period) {  
  59.       std::this_thread::sleep_for(default_period - elapsed);  
  60.     } else {  
  61.       AERROR  
  62.           << "Too much time consumption in TsyController looping process:"  
  63.           << elapsed.count();  
  64.     }  
  65.   }  
  66. }  

至此,我再进行sudo bash apollo.sh build就没有错误了:

 

本篇完

2020年12月25日 16:55

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