在本教程中,我将详细讲解如何在Linux系统中使用ROS(机器人作系统)来访问和控制CAN总线。我们将使用肥猫机器人公司的USB2CAN模块和SOULDE-Studio开发的USB2CAN_ROS软件包作为示例。

        代码链接:SOULDE-Studio/USB2CAN_ROS: ROS package for USB2CAN

        USB2CAN购买链接: https://e.tb.cn/h.RYk3qBV9viRttK8?tk=ZF8J5sK3VJOHU926

        USB2CAN 说明书以及SDK下载地址:百度网盘 请输入提取码

1. 硬件和软件需求

首先,我们需要准备以下硬件和软件:

  • DingLab品牌的USB2CAN模块(USB转2路CAN模块) 
  • Ubuntu Linux系统(建议Ubuntu 18.04或以上版本)
  • ROS环境(Melodic或Noetic版本)
  • 已安装的catkin工作空间

2. 安装USB2CAN_ROS软件包

2.1 获取代码

首先,我们需要将USB2CAN_ROS软件包克隆到catkin工作空间中:

cd ~/catkin_ws/src 
git clone https://github.com/SOULDE-Studio/USB2CAN_ROS.git 
cd .. 
catkin_make

2.2 安装USB2CAN规则文件

为了让Linux系统能够正确识别USB2CAN设备,我们需要安装udev规则文件:

cd ~/catkin_ws/src/USB2CAN_ROS/SDK 
sudo cp usb_can.rules /etc/udev/rules.d/ 
sudo udevadm trigger

3. 使用USB2CAN_ROS

3.1 环境设置与启动节点

首先,我们需要source环境变量,然后启动USB2CAN驱动节点:

source ~/catkin_ws/devel/setup.bash 
roslaunch usb2can_ros usb2can.launch

3.2 通信工作原理

当我们启动驱动节点后,系统会自动检测已插入的USB2CAN设备,并为每个设备创建相应的ROS话题:

  • /{DEVICE_NAME}/can_rx- 用于接收CAN总线上的数据
  • /{DEVICE_NAME}/can_tx- 用于发送数据到CAN总线

其中{DEVICE_NAME}是设备名称,如、等,根据实际接入的设备而定如USB2CAN0、USB2CAN1

3.3 运行测试示例

软件包提供了示例程序用于测试通信:

rosrun usb2can_ros user_node _device:=USB2CAN0

4. 自定义CAN通信应用

4.1 消息结构

在USB2CAN_ROS中,CAN帧数据通过消息类型进行传递,其包含以下几个关键字段:CANFrameMsg

  • channel: CAN通道号(USB2CAN模块支持双通道,可以是1或2)
  • can_id: CAN帧ID
  • frame_type: 帧类型(标准帧或扩展帧)
  • data_length: 数据长度
  • data: CAN帧数据

4.2 发送CAN消息

以下是发送CAN消息的示例代码:

// 创建节点句柄  
ros::NodeHandle nh;
std::string device = "USB2CAN0"; // 设备名称  

// 创建发布者  
ros::Publisher pub = nh.advertise<usb2can_ros::CANFrameMsg>(device+"/can_tx", 1000);  

// 创建CAN帧消息  
usb2can_ros::CANFrameMsg frame; frame.channel = 2; // 使用通道2  
frame.can_id = 0x123; // CAN ID为0x123  
frame.frame_type = 0; // 标准帧 
frame.data_length = 8; // 数据长度为8字节 
 
// 填充数据  
frame.data[0] = 0x01; 
frame.data[1] = 0x02; 
frame.data[2] = 0x03; 
frame.data[3] = 0x04; 
frame.data[4] = 0x05; 
frame.data[5] = 0x06; 
frame.data[6] = 0x07; 
frame.data[7] = 0x08;  

// 发布消息  

pub.publish(frame);

4.3 接收CAN消息

以下是接收CAN消息的示例代码:

// 回调函数,处理接收到的CAN帧 
void CANFrameMsgCallback(const usb2can_ros::CANFrameMsg::ConstPtr& msg){  
        ROS_INFO("Received CAN Frame: %d", msg->data_length);  
        for(int i = 0; i < msg->data_length; i++){  
                        ROS_INFO("Data[%d]: %d", i, msg->data[i]);  
                } 
        }         

// 创建订阅者  
std::string device = "USB2CAN0"; // 设备名称  
ros::Subscriber sub = nh.subscribe(device+"/can_rx", 1000, &CANFrameMsgCallback);

5. 底层实现

USB2CAN_ROS包通过封装底层SDK提供的API,使得用户可以通过ROS的发布/订阅机制来访问CAN总线:

// 打开USB2CAN设备  
handler_ = openUSBCAN(("/dev/" + device_).c_str());  

// 读取CAN数据的函数  
int ret = readUSBCAN(handler_, &frame.channel, &frame_info, frame_data, 1000);  

// 发送CAN数据的函数  
int ret = sendUSBCAN(handler_, msg->channel, &frame_info, frame_data);

6. 多设备支持

USB2CAN_ROS支持同时连接多个USB2CAN设备,每个设备可以分配不同的ID(最多4个)。在launch文件中,系统会自动为每个设备创建对应的ROS节点:

<node  
        name="usb2can_ros_node0"  
        pkg="usb2can_ros"  
        type="usb2can_ros_node"  
        output="screen">  
        <param name="device" type="string" value="USB2CAN0" /> 
</node>

总结

        通过本教程,我们学习了如何在Linux系统中使用ROS来访问CAN总线。使用USB2CAN_ROS软件包可以大大简化CAN总线通信的开发工作,让我们能够通过ROS的标准接口来发送和接收CAN消息。

        这种方式特别适合机器人开发,因为它可以将CAN总线设备(如电机控制器、传感器等)无缝集成到ROS生态系统中,便于系统集成和开发。

注意事项

  1. 使用前请确保已经正确安装USB2CAN模块的驱动和规则文件
  2. CAN总线通信参数(如波特率等)请参考USB2CAN模块说明书进行配置
  3. 发送CAN消息时,请确保data_length与实际的数据长度一致
  4. 多设备使用时,请确保每个设备的ID不重复

希望本教程对你在Linux系统下使用ROS调用CAN总线有所帮助!

笔记

        本教程基于SOULDE-Studio/USB2CAN_ROS仓库代码编写,主要面向需要在ROS环境下进行CAN总线通信的开发者。使用前请确保已正确安装USB2CAN设备的驱动程序和规则文件。

Logo

DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。

更多推荐