ROS采用SocketCAN进行通信

目录

  • 一、USB转CAN设备
    • 1.1 MKS CANable
    • 1.2 Linux SocketCAN驱动
    • 1.3 打开SocketCAN接口,并设置波特率
    • 1.4 在SocketCAN接口上发送/接收数据。
    • 1.5 设备缺点
  • 二、ROS socketcan_bridge驱动
    • 2.1 ROS提供三个层次的驱动库
    • 2.2 socketcan_bridge包
    • 2.3 socketcan_bridge_node
  • 三、基于ROS中转节点松耦合的CAN通信
    • 3.1 松耦合需求的原因
    • 3.2 中转节点
    • 3.3 CAN数据帧
    • 3.4 使用
  • 四、总结

一、USB转CAN设备

1.1 MKS CANable

MKS CANable是一款软硬件开源USB转CAN设备,基于STM32F0进行开发,工作温度为-40℃~+80℃,最高速率1Mbps,适配ROS的socketcan驱动。

官方网站:https://canable.io/

USB转CAN(SocketCAN)

该产品有两个版本,一个是MKS CANable Pro,一个是MKS CANable,区别如下:

该USB转CAN设备与周立功的CAN转USB设备数据传输流程不同,前者是利用的是SocketCAN,不是USB,驱动不一样。

MKS CANable芯片通过USB与Linux内核通信,让内核知道自己是一个Socketcan设备。

Linux识别到SocketCAN设备,采用 SocketCAN驱动与该设备通信,这种设备类似网络设备通过IP地址利用UDP进行通信,通过CAN ID作为地址,利用SocketCAN进行通信。

硬件接口

MKS CANable通过USB与内核通信,让其认为自己是一个socketcan设备!

1.2 Linux SocketCAN驱动

SocketCAN概念使用网络设备模型,允许多个应用程序同时访问一个CAN设备,并且单个应用程序能够并行访问多个CAN网络。

Linux利用SocketCAN库根据CAN的设备ID对其进行读写操作,CAN的数据结构在SocketCAN中被结构体定义,填充相应数据后发送即可。

SocketCAN通过引入新的协议族PF_CAN(ProtocolFamilyCAN)扩展了Linux中socketAPI,PF_CAN与其他协议族共存,例如Internet协议的PF_INET。

因此,与CAN总线的通信类似于通过socket使用Internet协议。

SocketCAN简介:https://en.wikipedia.org/wiki/SocketCAN

协议参考1:https://canable.io/getting-started.html#socketcan-linux

1.3 打开SocketCAN接口,并设置波特率

(1) 查看can id
ifconfig –a

(2) 关闭can(设置波特率之前必须先关闭can)
sudo ifconfig can0 down

(3) 设置can波特率
sudo ip link set can0 type can bitrate 1000000

(4) 使能can0
sudo ifconfig can0 up

1.4 在SocketCAN接口上发送/接收数据。

使用can-utils包可以在SocketCAN接口上发送/接收数据。

(1) 安装can-utils
sudo apt-get install can-utils

(2) 发送can数据帧,格式[can_id]#[can_data]
示例:cansend can0 123#1122334455667788

终端输入cansend,查看cansend用法

(3) 实时显示总线上收到的消息列表
candump can0

1.5 设备缺点

  • 操作复现:USB转CAN设备被sudo ifconfig can0 up 后,若在程序结束时,不手动sudo ifconfig can0 down 关闭USB转CAN设备,当工控机重启(关机可以正常运行)时,会导致USB转CAN设备无法正常运行

  • 终端提示:no sapce buffer avaliable

  • 设备状态:同时也可以看到此时USB转CAN设备的蓝灯常亮

  • 原因分析:结束程序后不执行down命令的话 ,重启过程中can设备实际上还在读写(蓝灯常亮),关闭程序并没有关闭底层的can,再次启动就会冲突,导致报错。但是关机不会,因为USB转CAN设备重新上电了。

  • 解决办法:一旦挂掉,只能重新插拔USB接口,无法用down和up命令再恢复。

因此,重启前,必须手动down下can设备

二、ROS socketcan_bridge驱动

2.1 ROS提供三个层次的驱动库

ROS针对socketcan提供了三个层次的驱动库,分别是ros_canopensocketcan_bridgesocketcan_interface

socketcan_interface是较为底层的包,与Linux的socketcan打交道。

socketcan_bridgeros中最常用的包,通过将接收到的topic转换为can数据发出去,或者把接收到的can数据转换为ros的topic。

ros_canopen是基于canopen应用协议的包,是上层应用协议。

2.2 socketcan_bridge包

安装命令
sudo apt-get install ros-melodic-socketcan-bridge

会自动安装下面三个包

  • ros-melodic-can-msgs: Topic中can协议的消息类型
  • ros-melodic-socketcan-bridge:话题与can信息进行转换的包
  • ros-melodic-socketcan-interface:socketcan-bridge依赖的包

socketcan_bridge功能包以三个节点的形式提供:socketcan_bridge_nodesocketcan_to_topic_nodetopic_to_socketcan_node

要从同一个 CAN 设备接收和发送帧,需要使用socketcan_bridge_node节点,来防止每个发送的消息都回显到接收主题。

自己的程序通过发布topic给socket_bridge_node节点将数据转为CAN信息发出去,数据流如下图,


2.3 socketcan_bridge_node

从SocketCAN设备接收帧并将这些帧发布到主题上,同时它侦听 CAN 消息并将这些消息发送到 SocketCAN。发送到 CAN 设备的帧不会作为接收消息发布。

  • 订阅的话题名称:sent_messages(can_msgs/Frame),此处收到的消息将被发送到 SocketCAN 设备。

  • 发布的话题名称:received_messages (can_msgs/Frame),在 SocketCAN 设备上接收到的帧在本主题中发布。

  • ROS节点参数:~can_device (string, default: can0),SocketCAN 设备的名称,默认情况下这些设备被命名为can0及以上。

如果需要修改话题名称或can id可以在launch中remap话题名称或设置param参数,如下


    
        
        
        

    

三、基于ROS中转节点松耦合的CAN通信

3.1 松耦合需求的原因

对于一些成熟的包,或者比较复杂的包,要想把其中的topic转为CAN数据发出去,有两种修改方式:

1. 修改源码
直接修改源码中相应topic的数据类型,或者在源码中新发布一个can_msgs/Frame数据类型,名称为sent_messages的topic

2.协议转发
新建一个中转节点,接收该复杂节点的topic(消息类型为该复杂节点的消息类型),将其转换为一个can_msgs/Frame数据类型,名称为sent_messages的topic发送出去。

第二种方式更为简单和快速,但会增加通信中转延时,ROS的节点通信是基于TCP/IP,对于本机节点通信而言,此延时大概在1ms以内(百兆网卡以上)。

因此建议采用第二种方式,更有利于维护软件的鲁棒性。

3.2 中转节点

对于该中转节点,需要订阅两个topic,发布两个topic

  • 订阅:
  1. 复杂节点发布的topic
  2. socketcan_bridge_node节点的topic:received_messages
  • 发布:
  1. 复杂节点订阅的topic
  2. socketcan_bridge_node节点的topic:sent_messages

话题数据流可参考下图

中转节点

3.3 CAN数据帧

socketcan_bridge_node的话题的消息类型都为ROS内置消息类型can_msgs/Frame

Header header
uint32 id
bool is_rtr
bool is_extended
bool is_error
uint8 dlc
uint8[8] data

需要填充的数据是iddlc(数据段长度),data

3.4 使用

一般把该中转节点与socketcan_bridge_node放在一个launch文件中。

如果socketcan_bridge_node节点的名称冲突了,可以在launch文件中添加group,或者remap话题名称。

四、总结

推荐CANable + socketcan_bridge包实现ROS中的CAN通信!

Github:
https://github.com/wanghuohuo0716/ros_can_driver

ROS socketcan_bridge包使用参考:
https://blog.csdn.net/zyf_to_utopia/article/details/116209605
https://blog.csdn.net/m0_58322903/article/details/121630592
https://blog.csdn.net/wangrunhuan/article/details/117962857

SocketCAN介绍:
https://en.wikipedia.org/wiki/SocketCAN

你可能感兴趣的:(ROS采用SocketCAN进行通信)