128 lines
9.7 KiB
Markdown
128 lines
9.7 KiB
Markdown
# 百度智慧交通组技术报告
|
||
|
||
## 概述
|
||
|
||
在本次比赛中,主要任务仍可归纳为“循线 + 定点任务”相结合的方式,大体上和往年相似。主要难度在于循线过程中存在直角弯、三岔路口、十字路口等特殊元素,并且任务点附近没有地标作为任务定位标识,同时任务动作对定位准确性要求较高。
|
||
|
||
出于节省学校经费的考虑,我们没有选择直接购买官方车模,而是仅购买了指定的电机,单独购置了符合要求的上位机板卡,自制了车模结构和控制电路部分。
|
||
|
||
## 下位机设计
|
||
|
||
### 自定义通信协议
|
||
由于购买的 Nvidia 官方以及仿制官方的 Jetson Orin Nano 载板(以下简称 “nano”)并没有直接引出 CAN 接口,并且对于 Linux 下 CAN 设备的调试开发也缺乏经验,所以选择了使用 nano 的 40pin 拓展接口中的串口设备与下位机主控板进行通信,对于其他模块的指令在下位机主控接收后转换成对应的 can 数据帧下发给其他模块,通信结构如下图所示。
|
||
|
||

|
||
|
||
在 nano 下发的指令中,需要控制车辆运动和执行机构动作,由于存在一些对参数“增量”修改的命令(如前进指定距离),为了避免因为通信出错导致类似指令漏发、多发,所以在通信机制中实现了校验和应答的机制。实现的自定义指令为定长帧,帧格式如下所示。
|
||
|
||
```
|
||
| 帧头 (1 byte) | 指令码 (1 byte) | 数据段 (8 byte) | CRC 校验值 (2 byte) |
|
||
| ------------ | -------------- | -------------- | ------------------ |
|
||
| 0xEB | 0x30 - 0x6F | 0x00 - 0xFF | 0x00 - 0xFF |
|
||
```
|
||
|
||
### 下位机主控设计
|
||
|
||

|
||
|
||
下位机主控采用了 AT32F403A 芯片作为主控,使用 配套的 AT32-WorkBench 工具能够非常快速的生成工程,加快开发速度。在功能上,下位机主控主要作为 nano 板卡和其他控制器模块的通信中继(将串口指令转发到 can 总线),并且还具备数字量输出(灯条和蜂鸣器控制)和电源分配功能。
|
||
|
||
在和上位机串口通信部分,使用了采用电容分压原理的隔离芯片,并配合隔离电源实现上下位机通信部分的隔离,避免对 nano 的接口产生损坏。
|
||
|
||
### 25GA 电机控制板设计
|
||
|
||

|
||
|
||
25GA 电机为官方指定的电机型号,该电机为直流有刷电机,具有减速箱和光栅编码器。
|
||
|
||
为了实现电机的速度控制,搭建了 H 桥控制电路。考虑到车辆自重可能较大,电机可能长时间工作在较大负载下,故没有使用诸如 tb67f450 的集成 H 桥芯片,而是使用 NMOS 和预驱自行搭建,这样可以获得较低的内阻和较好的散热性能。
|
||
|
||
主控芯片采用 AT32F413CBT7,主要考虑其具有 CAN 接口和充足的定时器等外设。
|
||
|
||
程序上,仅使用单速度环进行控制,采用简单的 PID 控制方式。由于车辆较重,该系统响应较为滞后,所以在参数整定上使用较大的积分值和较小的微分值,简单调参可以获得较好的控制效果。但仍然存在启动时负载较大,速度曲线上升迟缓的问题。经观察,大负载启动时,速度环输出上升速度足够快,基本上处于上限状态,故认为使用电流环作为内环并不能解决该问题。
|
||
|
||
输出上,使用互补 PWM,虽然会造成一定的热损耗,但是在一定程度上增加了响应性能。
|
||
|
||
此外,该电机存在编码器线数过低,在低速时不容易稳定控制的情况。在不改动编码器硬件的情况下,软件上配置 TIM 模块编码器模式为双边触发,对编码器信号进行四倍频。经观察,能够一定程度上提高低速状态下的控制精度。
|
||
|
||
### z 轴蜗杆电机控制板设计
|
||
|
||

|
||
|
||
z 轴使用带霍尔编码器的蜗杆电机,该电机减速机具有自锁特性,在位停止时仅需较小的保持力矩。该控制板硬件设计思路基本和 25GA 电机控制板一致,仅对于电源和主控进行了修改。主控更换了 AT32F425CBT7,由于互补输出方式在输出为 0 时仍存在等占空比的互补输出,噪声较大,而对于该电机响应性能要求不高,所以更换为受限单极模式输出。 相似的,为了提高电机控制精度,也设置了编码器双边触发模式,对编码器信号进行四倍频。
|
||
|
||
### x 轴步进电机控制板设计
|
||
|
||

|
||
|
||
由于 x 轴负载较小,为了提高机构运行速度和控制精度,使用步进电机驱动,齿轮齿条传动。为了简化开发流程,直接使用了 DRV8825 芯片(模块)对步进电机进行开环驱动,而为了保证位置的准确,又在步进电机轴体上粘贴了径向充磁的磁铁,利用次编码器检测转子位置。
|
||
|
||
程序上,提供了距离和绝对位置指令,上位机可设置使机构以指定速度、方向移动指定距离,或者以指定速度移动到设置位置。上电后先运行到限位位置校准零点。
|
||
|
||
### 6 路舵机控制板设计
|
||
|
||

|
||
|
||
控制板主要控制夹爪和摄像头的舵机,部分舵机负载电流较大。为了节省空间并简化电路,选用了 3 个 29302 分别为 6 路舵机供电。程序上可接收指令简单的设置舵机角度。
|
||
|
||
### 电源扩展板设计
|
||
|
||

|
||
|
||
电源控制板主要起到分电作用,提供电源和信号的扩展。每路均可使用低侧的 NMOS 控制电源开关,开关指令可经 can 总线下发。
|
||
|
||
## 结构设计
|
||
|
||
### 机架结构设计
|
||
|
||

|
||
|
||
机架采用玻璃纤维板、铝板、不锈钢制成。底板采用 4mm 玻璃纤维板,在非承载部分进行镂空减重,并且开有槽孔,用于在两侧安装机构和电路板。
|
||
|
||
主要机构安装在竖直的玻纤板上,该板下部用四方螺母进行固定,侧向使用两块铝板斜拉。开槽以安装z轴导轨以及主控板。
|
||
|
||
电机安装于底板下方,使用定制的 201 不锈钢钣金件和底板连接。轮子安装于电机轴上,两钣金件在轴的两端提供支承作用,减少因为自重太大导致轴产生过于明显的弯曲,优化车辆行驶中的“跳动”现象。
|
||
|
||
### x 轴机构设计
|
||
|
||
x 轴机构安装在一水平放置的微型导轨上,使用齿轮齿条进行传动。x 轴末端可以 180 度旋转,末端为夹爪。
|
||
|
||
### z 轴机构设计
|
||
|
||
为了实现 z 轴快速运行并且可自锁的要求,z 轴选用了带编码器的蜗杆减速电机,使用同步带进行传动。电机固定在车辆底部,z 轴机构固定在同步带上,使用压板在安装时张紧。导向上使用两列平行的微型直线导轨。
|
||
|
||
## 上位机程序设计
|
||
|
||
### 上位机环境配置概述
|
||
|
||
上位机程序主要基于 python 和 C/C++,为了保证和原有环境不产生冲突,使用 conda 创建了 python 的开发和运行环境。
|
||
|
||
在程序实际运行中,我们发现当推理开启时,一个模型的进程需要占用 2G 左右的内存,即使是在代码中开启了内存优化,并且指定大小,实际占用并没有明显区别。当开启多个推理进程时,会导致内存占满,使得某些进程被 kill 掉。由于规则限制最大只能使用 8G 内存的 nano 板卡,所以挂载了一个较大的 swap 分区,使用磁盘缓存保证不会出现物理内存占用过高的情况,实际测试下,未见明显的性能影响。
|
||
|
||
此外,为了保证开机自启的效果,我们构建了一个守护进程,使用 systemctl 管理。
|
||
|
||
### 上位机程序总体设计
|
||
|
||
为了保证程序的高效运行,上位机程序总体采用“生产者-消费者”模型,所有进程由守护进程管理,首先由图像采集进程采集图像并储存在缓冲区中;推理进程从缓冲区获取图像,推理完成后将推理结果储存;控制线程需要推理结果时,向推理服务器请求暂存的推理结果即可,所有进程间请求均使用 zmq 的 “请求-应答” 模式。通过上述的结构模式,可以保证获取数据最新且请求速度较快。
|
||
|
||
### 执行机构接口程序设计
|
||
|
||
执行机构接口作为 python 模块导入控制进程的程序中,本体基于 C 编译成动态链接库,然后通过 cython 构建成 python 模块。
|
||
|
||
程序接收传入参数并封装成数据包,通过串口设备发送到下位机主控,然后接收下位机主控的响应,校验响应数据后返回。实现了应答超时和应答出错返回的机制。
|
||
|
||
### 图像采集服务器程序设计
|
||
|
||
图像采集服务器程序基于 C/C++ 编写,是一个独立的进程。该进程使用 opencv 读取摄像头图像,每个摄像头对象构造一个采集和应答线程,保证获取和响应的图像最新。
|
||
|
||
### 推理服务器程序设计
|
||
|
||
### 赛道线回归模型概述
|
||
|
||
### 任务主程序设计
|
||
|
||
任务主程序将每个任务封装成对象,根据实际需求放入队列。程序执行时,任务对象依次出队。任务的执行按照 “搜寻-执行-后处理” 的方式运行,当执行某一任务时,先循环搜寻任务标志,待搜寻到可以进入任务的条件后,进入任务执行函数,函数内执行校准、夹持、伸展等任务。执行完成后,进入后处理阶段,该阶段可以设置下一任务的相关参数,并将执行机构运动到下一任务的预备位置。如果该任务不被开启,则执行一个任务不开启时才调用的函数,使执行机构运动到中立位置,保证下一任务开启时不会发生冲撞。
|
||
|
||
### 守护和交互程序设计
|
||
|