写在前面,这将是我最后一次直接使用VScode的深色主题来粘贴代码了,看得我眼睛晕。
如果有CSS大佬来指点以下如何把段内的行间距改的特别小就不胜感激了。
使用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对车辆底盘信号的要求,第二步是进行车辆底盘信号database(DBC)文件进行编辑,设置通信的网络结构,每个信号的初值、符号类型,精度,大小范围,取值等,进而组合成相应的CAN通信报文(message)与Apollo进行通信。下面使用CANdb++软件对DBC文件进行编辑,有较好的可视化界面,该软件目前只适用于Windows系统。
因为DBC文件后面会根据Apollo的转译脚本工具,将底盘定义的报文(message)、信号(signal)转化为C++程序代码,因此在编辑DBC时,对信号的名称定义、注释、赋值等就要符合C++语言定义规范,这样以确保在后期调试时不会因为DBC文件的问题无法调通CANBUS通信。根据Apollo代码要求,我们总结了以下注意事项:
#### 1. 控制信号名称建议为 ACU
在定义网络上ECU名称时,建议定义Apollo端的控制器名称为ACU(Apollo 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类型的反馈和控制信号在DBC中Value 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的名称一致,ge3的DBC内定义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吧
如果在执行过程中出现了报错和警告,主要有三种情况:
- 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 *
- Yaml.load有问题,出现warning。
with open(sys.argv[1], 'r') as fp:
conf = yaml.load(fp,Loader=yaml.FullLoader) #这步是防止一个新版yaml下yaml.load不安全的warnning
gen(conf)
- 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<Vcudbsfrequest154, true>();
AddSendProtocolData<Vcuepsfcontrolrequest469, true>();
AddSendProtocolData<Vcuepsrcontrolrequest101, true>();
AddSendProtocolData<Vcuvehiclediagnosis301, true>();
AddSendProtocolData<Vcuvehiclestatus1303, true>();
// Report Messages
AddRecvProtocolData<Dbsfstatus142, true>();
AddRecvProtocolData<Epbstatus375375, true>();
AddRecvProtocolData<Epsfstatus401, true>();
AddRecvProtocolData<Epsrstatus111, true>();
AddRecvProtocolData<Iecucontroldistributed505, true>();
AddRecvProtocolData<Iecucontrolflag501, true>();
AddRecvProtocolData<Iecucontrolibc503, true>();
AddRecvProtocolData<Iecucontrolpower504, true>();
AddRecvProtocolData<Iecucontrolsteering502, true>();
AddRecvProtocolData<Imuacceleration181, true>();
AddRecvProtocolData<Imuangular281, true>();
AddRecvProtocolData<Imueuler381, true>();
AddRecvProtocolData<Remotecontrolio10a, true>();
AddRecvProtocolData<Remotecontrolshake210b, true>();
AddRecvProtocolData<Vcuepbrequest310310, true>();
AddRecvProtocolData<Vcuvehiclestatus2304, true>();
}
可以看到自动识别的控制报文时154/469/101/301/303五个报文,但是这并不是我想要的,我们这台车的API是在Iecu*的那4个报文:501/502/503/504里面定义的,这些才应该是"Control Messages"。
修改
针对上面的问题,我参考了南阳理工学院袁珺博士的配适文件,发现他们总共三个报文,发送和接受的关系是对的。
NylgMessageManager::NylgMessageManager() {
// Control Messages
AddSendProtocolData<Vcumcurequest160, true>();
// Report Messages
AddRecvProtocolData<Mcudrivemotorfeedbackmsg60, true>();
AddRecvProtocolData<Mcutorquefeedback10, true>();
}
我本着从简单到一般的方法,向同事们要来了他们那台车的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的基本代码模板了。我们需要把文件内的代码**拷贝**到apollo的canbus层内,进行代码适配添加。
![output](images/vehicle_adaption_tutorial/output.png)
**注意**:把这个output文件夹内生成的代码模板拷贝至相应的apollo目录后,要删除该文件夹,如果不删除该文件夹,后期编译apollo时会报错。该文件夹有保护权限,请在apollo的docker内执行删除代码:
```
rm -rf output/
```
要记得删除output文件夹。
剩下的是合并文件了,下篇再更新对应内容。
2020年12月17日 18:02
于宁波天尚元振狮路365号工厂二楼