安全路透社
当前位置:安全路透社 > 网络转载 > 正文

如何控制一辆福特Fusion概念车

6666.jpg

近期,我跟一位在Voyage公司上班的朋友在尝试对一辆福特Fusion汽车的A / C系统实现编程控制。Voyage是汽车自动驾驶领域内的一家专业公司,他们想要实现的终极目标是:对于世界上的任何一个人,他都可以随时随地召唤一辆汽车直接开到他的家门口,并将他安全地送达到目的地,而且价格也非常便宜。对于Voyage来说,他们将不可避免地给乘客提供汽车关键功能的控制权,因为总有一天开车的将不再是我们人类,而这一天马上就要到来了。

CAN总线介绍

CAN是控制器局域网络(Controller Area Network, CAN)的简称,是由以研发和生产汽车电子产品著称的德国BOSCH公司开发的,并最终成为国际标准(ISO 11898),是国际上应用最广泛的现场总线之一。

一台现代化汽车拥有大量的控制系统,这些控制系统的作用与Web应用中各种微服务的作用是非常相似的。对于一台电动汽车来说,它拥有安全气囊、自动刹车系统、电动助力转向系统、音响系统、电动车门、后视镜调整系统、以及电池与充电系统等等。这些系统需要相互通信并获取其他系统的运行状态。在1983年,德国BOSCH公司便开发CAN总线来解决这个复杂的问题。

你可以把CAN总线看成一个简单的网络,车上的任何系统都可以监听系统并发送指令。它以巧妙的方式整合了所有这些复杂的组件,并给我们的汽车提供各种各样的现代化功能。下图为一辆1988年款的宝马8系,这也是全球第一台采用了CAN总线的汽车:

8888.jpg

自动驾驶车辆以及和CAN总线

近些年来,随着自动驾驶汽车的快速发展,CAN总线的概念也得到了普及。为什么呢?因为自动驾驶汽车领域内的绝大多数公司都不会从零开始设计和制造自家的汽车,而且他们还需要想办法通过编程的方式来控制汽车。

通过对汽车CAN总线进行逆向工程分析,工程师将可以通过软件来向汽车发送控制命令。比如说,最常用的控制命令有旋转方向盘、加速(踩油门)和制动(踩刹车)。使用 LIDAR传感器的汽车就可以像超人一样俯揽这个世界,然后,汽车内置计算机便可以决定是否向CAN总线发出诸如,加速、刹车指令。

当然并不是每一辆汽车都可以进行自动驾驶,Voyage之所以选择福特Fusion概念车,上述内容便是原因之一。LiDAR作为激光雷达测距传感器,感应距离可以达到200 米。下图为LIDAR技术的实例图:

77777.jpg

破解CAN总线

在破解福特Fusion概念车CAN总线之前,我打开了一本书(汽车黑客手册),然后开始工作。准备工作完成之后,打开本书的第二章,看这三项内容,CAN总线协议、帧结构以及CAN总线。

CAN总线

CAN总线自1994年诞生以来以来一直是美国汽车和轻型卡车的标准,但到2008年(2001年为欧洲车辆年)之前,它一直不是强制性的协议。

CAN总线通过CAN收发器接口芯片82C250的两个输出端CANH和CANL与物理总线相连,而CANH端的状态只能是高电平或悬浮状态,CANL端只能是低电平或悬浮状态。这就保证不会在出现在RS-485网络中的现象,即当系统有错误,出现多节点同时向总线发送数据时,导致总线呈现短路,从而损坏某些节点的现象。

也就是说CAN使用差分信号,这意味着当信号进入系统时,CAN总线信号会在一条线路曾上升电压趋势,并利用另一条线路维持平衡。分信号用于必须具有容错性环境,如汽车制造系统。

还有一点需要注意的是,CAN节点在错误严重的情况下具有自动关闭输出功能,以使总线上其他节点的操作不受影响,从而保证不会出现像在网络中,因个别节点出现问题,使得总线处于“死锁”状态。而且,CAN具有的完善的通信协议可由CAN控制器芯片及其接口芯片来实现,从而大大降低系统开发难度,缩短了开发周期。

下图显示的是示波器中观察到的原始CAN总线信号:

che1.jpeg

通过CAN总线传输的数据包并不是标准的。 每个CAN总线包都包含四个关键要素:

1.仲裁ID(Arbitration ID):仲裁ID是一种广播消息,代表的是需要进行数据通信的设备ID,不过一台设备可以发送多个仲裁ID。如果两个CAN数据包同时在总线上进行发送,那么仲裁ID较小的那个数据包将优先传输;

2.CAN总线标识符扩展(IDE):该位始终为标准CAN总线协议,这部分数据永远为o。

3.数据长度代码(DLC):数据大小,范围是0到8个字节。

4.数据取决于本身,标准CAN总线数据包携带的数据最多可达8字节,但有些系统可通过填充数据包强制达到8字节。

标准CAN总线数据包格式

che2.png

CAN框架

为了打开和关闭A / C系统,我们需要找到正确的CAN总线(一辆汽车可以有多个)。福特Fusion概念车至少拥有4条总线(厂商记录),

其中3条以500kbps(高速CAN)运行,其中一条以125kbps(中速CAN)运行。

OBD-II端口暴露了其中的两条总线:HS1和HS2,但这台汽车上这两条总线有防火墙的保护,因此不允许我们向其发送欺骗指令。在Alan(Voyage员工)的帮助下,我们解决了这个问题并成功拿到了HS1、HS2、HS3和MS的访问权。OBD-II端口后面有一个名叫Gateway Module的设备,所有的总线最终都要将数据传输到这个设备中,这就是我们的解决方案。

che3.jpeg

由于由于A / C系统可以直接与汽车多媒体接口(SYNC)进行对接,并利用计算机可修改,所以我们直接访问MS总线。

但是我们如何让我们的计算机能够读写CAN数据包? 答案是SocketCAN。这是开源CAN驱动程序,这是一个由德国大众公司向Linux内核基金会研发的开源CAN驱动和网络栈协议集。我们可以把车辆的GND、MSCANH、MSCANL3条线连接到Kvaser Leaf Light HSv2(亚马逊上卖300美元)和CANable(Tindie上卖25美元)设备上,在另一端,使用安装有较新版本Linux系统电脑相连,最后将CAN总线作为网络设备识别加载:

modprobe can
modprobe kvaser_usb
ip link set can0 type can bitrate 1250000
ifconfig can0 up

加载后我们可以利用candump can0指令查看流量信息

can0  33A   [8]  00 00 00 00 00 00 00 00                                                                      
can0  415   [8]  00 00 C4 FB 0F FE 0F FE                                                                      
can0  346   [8]  00 00 00 03 03 00 C0 00                                                                      
can0  348   [8]  00 00 00 00 00 00 00 00                                                                      
can0  167   [8]  72 7F FF 10 00 19 F8 00                                                                      
can0  3E0   [8]  00 00 00 00 80 00 00 00                                                                      
can0  167   [8]  72 7F FF 10 00 19 F7 00                                                                      
can0  34E   [8]  00 00 00 00 00 00 00 00                                                                      
can0  358   [8]  00 00 00 00 00 00 00 00                                                                      
can0  3A4   [8]  00 00 00 00 00 00 00 00                                                                      
can0  216   [8]  00 00 00 00 82 00 00 00                                                                      
can0  3AC   [8]  FF FF FF FF FF FF FF FF                                                                      
can0  415   [8]  00 00 C8 FA 0F FE 0F FE                                                                      
can0  083   [8]  00 00 00 00 00 01 7E F4                                                                      
can0  2FD   [8]  D4 00 E3 C1 08 52 00 00                                                                      
can0  3BC   [8]  0C 00 08 96 01 BB 27 00                                                                      
can0  167   [8]  72 7F FF 10 00 19 F7 00                                                                      
can0  3BE   [8]  00 20 AE EC D2 03 54 00                                                                      
can0  333   [8]  00 00 00 00 00 00 00 00                                                                      
can0  42A   [8]  D6 5B 70 E0 00 00 00 00                                                                      
can0  42C   [8]  05 51 54 00 90 46 A4 00                                                                      
can0  33B   [8]  00 00 00 00 00 00 00 00                                                                      
can0  42E   [8]  93 00 00 E1 78 03 CD 40                                                                      
can0  42F   [8]  7D 04 00 2E 66 04 01 77                                                                      
can0  167   [8]  72 7F FF 10 00 19 F7 00                                                                      
can0  3E7   [8]  00 00 00 00 00 00 00 00                                                                      
can0  216   [8]  00 00 00 00 82 00 00 00                                                                      
can0  415   [8]  00 00 CC F9 0F FE 0F FE                                                                      
can0  3A5   [8]  00 00 00 00 00 00 00 00                                                                      
can0  3AD   [8]  FF FF FF FF FF FF FF FF                                                                      
can0  50B   [8]  1E 12 00 00 00 00 00 00

但是,我们这样去监控总线的数据流量,就相当于用眼睛来观察声音信号的振幅一样,我们不仅很难弄清楚总线到底在传输什么数据,而且也很难发现其中的模式或规律。因此,我们需要像分析声音频率一样来分析这个问题,我们可以调用cansniffer.和cansniffer来查看相应的ID,然后主要分析CAN框架的数据区域中具体发生了哪些变化。我们通过研究后发现,我们可以利用特定的ID来过滤掉那些我们不需要的数据,然后只留下与我们问题相关的那些数据。

以下是cansniffer在MS中速总线的抓包示例,我们正在对所有通过串口的数据包进行过滤,只需要CAN id为355、356和358的数据包。同时,我按下了汽车中的温度调节按钮,我们可以看到数据下方出现了001C00000000,它代表的就是我们按下调节按钮的操作。

chehouer.gif

接下来就是把A/C系统功能连接到我们运行于汽车内的微型计算机,该计算机为AI操作系统(ROS),而幸运的是,利用前述提及的SocketCAN和ROS中的一个模块,就能很容易实现连接和操作。socketcan_bridge可以将我们的CAN框架转换成一种ROS可接受的消息格式。太棒了!下面就是解码数据的实例:

if frame.id == 0x356:
raw_data = unpack('BBBBBBBB', frame.data)
fan_speed = raw_data[1] / 4
driver_temp = parse_temperature(raw_data[2:4])
passenger_temp = parse_temperature(raw_data[4:6])

解码后的数据保存在CelsiusReport.msg之中

bool auto
bool system_on
bool unit_on
bool dual
bool max_cool
bool max_defrost
bool recirculation
bool head_fan
bool feet_fan
bool front_defrost
bool rear_defroststring driver_temp
string passenger_temp

在按下了汽车内所有的相关功能之后,我们得到了下面这个清单列表:

CONTROL_CODES = {
'ac_toggle': 0x5C,
'ac_unit_toggle': 0x14,
'max_ac_toggle': 0x38,
'recirculation_toggle': 0x3C,
'dual_temperature_toggle': 0x18,
'passenger_temp_up': 0x24,
'passenger_temp_down': 0x28,
'driver_temp_up': 0x1C,
'driver_temp_down': 0x20,
'auto': 0x34,
'wheel_heat_toggle': 0x78,
'defrost_max_toggle': 0x64,
'defrost_toggle': 0x4C,
'rear_defrost_toggle': 0x58,
'body_fan_toggle': 0x04,
'feet_fan_toggle': 0x0C,
'fan_up': 0x2C,
'fan_down': 0x30,
}

现在,我们就可以直接向ROS节点发送字符串数据,然后通过它来将我们发送的信息转换成汽车可以识别的特殊代码:

rostopic pub /celsius_control celsius/CelsiusControl ac_toggle

分析结果

我们现在可以向CAN总线发送相应的CAN控制代码了,这些代码与我们按下汽车物理实体按钮时所发出的总线控制命令是一样的。这也就意味着,我们可以远程改变汽车的车内温度了。我们成功了!

9999.jpg

当然了,为了更好地提升用户在乘坐Voyage自动驾驶汽车时的体验度,仅仅做到这些还远远不够。因此我希望将来还能够与Voyage的工作人员继续合作,并设计出更多客户喜欢的功能。

*参考来源:voyage,饭团君编译

未经允许不得转载:安全路透社 » 如何控制一辆福特Fusion概念车

赞 (0)
分享到:更多 ()

评论 0

评论前必须登录!

登陆 注册