写在前面,这将是我最后一次直接使用VScode的深色主题来粘贴代码了,看得我眼睛晕。

如果有CSS大佬来指点以下如何把段内的行间距改的特别小就不胜感激了。 

   

  1. 使用DBC生成对应文件

该步骤使用Apollo提供的工具文件,路径在apollo\modules\tools\gen_vehicle_protocol\,参考技术文档的内容进行操作,技术文档的路径为apollo\docs\technical_tutorial\apollo_vehicle_adaption_tutorial_cn.md。

下面对照技术文档来进行DBC文件的转换。

根据技术文档的内容,首先要把DBC文件用文本的形式打开,并保存为UTF-8的格式。

Canbus适配代码可以使用apollo的工具生成,在转换代码前,要保证DBC按照上述的DBC文件要求完成,并通过gedit打开dbc文件,另存转码为UTF-8格式保存。

文件放置

1)将DBC文件放置指定目录下,目录`apollo/modules/tools/gen_vehicle_protocol`内。

但是本次只使用了CAN1的DBC,即tsy_can0.dbc。

需要注意的是DBC文件有很多要求,诸如技术文档中所描述的:

### DBC文件要求

   

熟悉了上述Apollo对车辆底盘信号的要求,第二步是进行车辆底盘信号databaseDBC)文件进行编辑,设置通信的网络结构,每个信号的初值、符号类型,精度,大小范围,取值等,进而组合成相应的CAN通信报文(message)与Apollo进行通信。下面使用CANdb++软件对DBC文件进行编辑,有较好的可视化界面,该软件目前只适用于Windows系统。

   

因为DBC文件后面会根据Apollo的转译脚本工具,将底盘定义的报文(message)、信号(signal)转化为C++程序代码,因此在编辑DBC时,对信号的名称定义、注释、赋值等就要符合C++语言定义规范,这样以确保在后期调试时不会因为DBC文件的问题无法调通CANBUS通信。根据Apollo代码要求,我们总结了以下注意事项:

#### 1. 控制信号名称建议为 ACU

在定义网络上ECU名称时,建议定义Apollo端的控制器名称为ACUApollo Control Unit)。

   

![name](images/vehicle_adaption_tutorial/name.jpg)

#### 2. CAN信号ID建议不大于2048

目前乘用车CAN通信建议采用标准帧格式(CAN Standard 2.0),Apollo可支持扩展帧。

   

![ID](images/vehicle_adaption_tutorial/messageID_define.jpg)

#### 3. 注释不能有回车符和换行符,comment(注释)必须为英文

每帧报文(message)如果有注释,注释内不要有换行,不能写中文,必须为英文格式。

   

![comment](images/vehicle_adaption_tutorial/comment.jpg)

##### 4. VAL_(枚举值)(Value Description)需要使用英文,且不能有相同定义名称,必须为字母或字母和数字组合,不能有符号。

对于大部分状态反馈信号和控制信号,如档位反馈,驾驶模式反馈等,需要对信号进行定义,在信号定义的Value Description项内进行定义,定义的名称要遵循C++命名规范,要求使用英文,且不能有相同定义名称,必须为字母或字母和数字组合,不能有符号。如下图是的档位反馈信号的Value Description定义。

   

![gear1](images/vehicle_adaption_tutorial/gear1.jpg)

##### 5. 反馈信号和控制信号中如车速,轮速,加速度,踏板位置(百分比)等double类型的反馈和控制信号在DBCValue Description项中必须为空。

对于实时数值反馈信号和数值控制信号,如车速(实际车速)、轮速反馈(实际轮速),踏板控制(百分比),转角控制(实际转角值)等,此类信号在定义Value Description项中不能加任何内容。

   

![val](images/vehicle_adaption_tutorial/val.jpg)

##### 6. 转向信号的范围,在定义时要填写准确的取值范围,注意控制转角的精度一般不高于0.05deg,踏板百分比精度(factor)不高于0.1

对于所有报文的Byte Order,一个DBC内的信号只能统一定义,全部是Motorola格式或者全部是Intel格式。

   

![define](images/vehicle_adaption_tutorial/define.jpg)

文件修改

2)修改DBC转换脚本的配置文件:下面以GE3车型添加为例,在`apollo/modules/tools/gen_vehicle_protocol`目录下,复制默认存在的`mkz_conf.yml`文件并重命名为`ge3_conf.yml`,修改该配置文件,如下图所示:

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

`dbc_file`:填写对应你的DBC文件名称,DBC文件名称一般以车型名称命名,并以`.dbc`结束;

   

`protocol_conf`:与上述DBC文件名称命名相同,填写`ge3.yml`

   

`car_type`:填入车型名称;

   

`sender_list[ ] `:发送列表,这里默认为空;

   

`sender`:此处修改为与DBC内定义的Apollo的名称一致,ge3DBC内定义Apollo名称为SCU

文档中说重命名为ge3_conf.yml,对于我们来说,就是复制一个并重命名为tsy_conf.yml,并根据提示修改文档内容。dbc_file为我们要转换的dbc文件tsy_can1.dbc;protocol_conf名称和dbc保持一致,叫做tsy_can1.yml;car_type我们叫做TSY(这里注意一下,car type是car brand的下级,所以最好car type叫W31之类的,car brand叫TSY)sender这里应该是写错了,不应该是VCU,而应该是iECU

执行转换代码

3)完成`ge3_conf.yml`配置文件设置,启动docker,进入Apollo的容器后,在`apollo/modules/tools/gen_vehicle_protocol`目录下,找到DBC转化工具`gen.py`,执行代码:

```

cd modules/tools/gen_vehicle_protocol

python gen.py ge3_conf.ymal

```

   

这段代码需要先进入容器,但是第二句应该是python gen.py ge3_conf.yml

而不是.ymal

如果在执行过程中出现了报错和警告,主要有三种情况:

  1. Import部分有问题,出现error。

#from modules.tools.gen_vehicle_protocol.gen_proto_file import gen_proto_file

#from modules.tools.gen_vehicle_protocol.gen_protocols import gen_protocols

#from modules.tools.gen_vehicle_protocol.gen_vehicle_controller_and_manager import gen_vehicle_controller_and_manager

#from modules.tools.gen_vehicle_protocol.extract_dbc_meta import extract_dbc_meta

from gen_proto_file import *

from gen_protocols import *

from gen_vehicle_controller_and_manager import *

from extract_dbc_meta import *

#以上的修改是因为原程序出现报错no module named "modules",后来发现是引用不对

#因为是同级的引用,所以可以这样直接from

#并且后面没有涉及到gen_proto_file.xx的操作,所以不是直接import gen_proto_file

#而是from gen_proto_file import *

  1. Yaml.load有问题,出现warning。

    with open(sys.argv[1], 'r'as fp:

        conf = yaml.load(fp,Loader=yaml.FullLoader) #这步是防止一个新版yamlyaml.load不安全的warnning

    gen(conf)

  1. Dbc文件有问题,会报错quotation not match,引号问题。

    将DBC用文本打开后,只留下BO和VAL项。

生成转换代码

如果前面一切正常,则会在docker界面显示类似的输出:

然后在output文件夹内存在以下内容:

Protocol中是各个报文的DBC转码,如下所示:

可是我却发现了一些问题,在最后的docker界面中,可以看到是生成了5个control,16个report。总共是21个报文,这在can1的dbc中也是如此,但是当我打开自动生成的tsy_message_manager.cc的时候,发现问题了,文件路径在…\gen_vehicle_protocol\output\vehicle\tsy\tsy_message_manager.cc。

TsyMessageManager::TsyMessageManager() {

  // Control Messages

  AddSendProtocolData<Vcudbsfrequest154true>();

  AddSendProtocolData<Vcuepsfcontrolrequest469true>();

  AddSendProtocolData<Vcuepsrcontrolrequest101true>();

  AddSendProtocolData<Vcuvehiclediagnosis301true>();

  AddSendProtocolData<Vcuvehiclestatus1303true>();

   

  // Report Messages

  AddRecvProtocolData<Dbsfstatus142true>();

  AddRecvProtocolData<Epbstatus375375true>();

  AddRecvProtocolData<Epsfstatus401true>();

  AddRecvProtocolData<Epsrstatus111true>();

  AddRecvProtocolData<Iecucontroldistributed505true>();

  AddRecvProtocolData<Iecucontrolflag501true>();

  AddRecvProtocolData<Iecucontrolibc503true>();

  AddRecvProtocolData<Iecucontrolpower504true>();

  AddRecvProtocolData<Iecucontrolsteering502true>();

  AddRecvProtocolData<Imuacceleration181true>();

  AddRecvProtocolData<Imuangular281true>();

  AddRecvProtocolData<Imueuler381true>();

  AddRecvProtocolData<Remotecontrolio10atrue>();

  AddRecvProtocolData<Remotecontrolshake210btrue>();

  AddRecvProtocolData<Vcuepbrequest310310true>();

  AddRecvProtocolData<Vcuvehiclestatus2304true>();

}

可以看到自动识别的控制报文时154/469/101/301/303五个报文,但是这并不是我想要的,我们这台车的API是在Iecu*的那4个报文:501/502/503/504里面定义的,这些才应该是"Control Messages"。

修改

针对上面的问题,我参考了南阳理工学院袁珺博士的配适文件,发现他们总共三个报文,发送和接受的关系是对的。

NylgMessageManager::NylgMessageManager() {

  // Control Messages

  AddSendProtocolData<Vcumcurequest160true>();

   

  // Report Messages

  AddRecvProtocolData<Mcudrivemotorfeedbackmsg60true>();

  AddRecvProtocolData<Mcutorquefeedback10true>();

}

我本着从简单到一般的方法,向同事们要来了他们那台车的DBC文件,希望能从里面找到一些可以参考的地方。

果然不出我所料,让我找到了突破点。

问题就在这个transmitter(发送者)这一项,我可以大胆猜测袁珺博士那边在nylg_conf.yml里的sender写的是VCU,如果这一项不是VCU或者为空,那么就全都是report messages。

所以现在对于DBC文件修改的第一步就应该是将iECU发出的报文中transmitter这一项使用下面的add添加iECU。

善后

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

这时在`apollo/modules/tools/gen_vehicle_protocol`目录下,会生成一个`output`文件夹,文件夹内有2个文件夹,一个是`proto`文件夹,一个是`vehicle`文件夹;这两个文件内的代码内容就是我们要适配canbus的基本代码模板了。我们需要把文件内的代码**拷贝**apollocanbus层内,进行代码适配添加。

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

   

**注意**:把这个output文件夹内生成的代码模板拷贝至相应的apollo目录后,要删除该文件夹,如果不删除该文件夹,后期编译apollo时会报错。该文件夹有保护权限,请在apollodocker内执行删除代码:

```

rm -rf output/

```

要记得删除output文件夹。

剩下的是合并文件了,下篇再更新对应内容。

2020年12月17日 18:02

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