基于ROS的上下位机CAN通讯


序言

先前采用了串口进行上下位机通讯,由于需要USB转串口,会出现通讯不上的问题。
之后了解了CAN通讯,发现相比串口通信更稳定,在编程上也相对自由些


虚拟 CAN 体验

安装 can-utils 包(主要用其中包含的 candump 工具)

sudo apt install can-utils

具体体验步骤

  1. 加载虚拟 CAN 模块
    sudo modprobe vcan
  2. 添加 can0 网卡
    sudo ip link add dev can0 type vcan
    此时通过 ifconfig -a 命令可以看到比平时多了一个 can0,但此时状态为:<NOARP>
  3. 启动 can0
    sudo ip link set dev can0 up
    再次查看 can0 状态,此时为:<UP,RUNNING,NOARP>
  4. 启动 candump 命令,监控 can0 端口的数据
    candump can0
  5. 使用 cansend 命令,向 can0 端口发布数据:123#456789
    cansend can0 123#456789
    此时,candump 窗口接收到数据:can0 123 [3] 45 67 89

注意
使用 cansend 发布数据需要有一定格式,否则会报错,官方声明如下

cansend - send CAN-frames via CAN_RAW sockets.

Usage: cansend <device> <can_frame>.

<can_frame>:
 <can_id>#{data}          for 'classic' CAN 2.0 data frames
 <can_id>#R{len}          for 'classic' CAN 2.0 data frames
 <can_id>##<flags>{data}  for CAN FD frames

<can_id>:
 3 (SFF) or 8 (EFF) hex chars
{data}:
 0..8 (0..64 CAN FD) ASCII hex-values (optionally separated by '.')
{len}:
 an optional 0..8 value as RTR frames can contain a valid dlc field
<flags>:
 a single ASCII Hex value (0 .. F) which defines canfd_frame.flags

Examples:
  5A1#11.2233.44556677.88 / 123#DEADBEEF / 5AA# / 123##1 / 213##311223344 /
  1F334455#1122334455667788 / 123#R / 00000123#R3
  1. 关闭 can0
    sudo ip link set dev can0 down
    此时通过 ifconfig -a 命令可以看到 can0 状态变回:<NOARP>
  2. 删除 can0
    sudo ip link del dev can0
    此时使用 ifconfig -a 命令已经看不到 can0 了

使用 ros can

安装相关依赖(此处以 Ubuntu18.04 为例,具体 ROS 版本号对应需要更改)

sudo apt-get install ros-melodic-can-msgs

sudo apt-get install ros-melodic-socketcan-bridge

sudo apt-get install libmuparser-dev

具体使用步骤

  1. 启动 master 节点
    roscore
  2. 启动 ROS 的 CAN 数据转ROS话题节点
    rosrun socketcan_bridge socketcan_to_topic_node
  3. 启动 ROS CAN数据转换后的话题节点
    rostopic echo /received_messages
  4. 启动 candump 监控 can0
    camdump can0
  5. 使用 cansend 命令发布数据
    cansend can0 123#456789
  6. 此时可以在 3.4. 窗口中分别接收到 CAN 转换后的数据和 CAN 的原生数据。

在 ROS 代码中使用 CAN 通讯

涉及到的包以及话题消息

  1. socketcan_bridge 包:主要是两个用于转换 CAN 数据和 ROS 话题数据的节点(topic_to_socketcan_node,socketcan_to_topic_node)
  2. can_msgs::Frame 消息:用于存储 CAN 消息,官方数据结构如下
std_msgs/Header header
  uint32 seq
  time stamp
  string frame_id
uint32 id
bool is_rtr
bool is_extended
bool is_error
uint8 dlc
uint8[8] data

主要成员变量解析
id:CAN 通讯的 ID
dlc:数据字节长度
data:用于 CAN 数据存储的数组

简单示例

  • launch文件,用于启动数据转换节点和示例节点
<launch>
    <!-- topic 转 CAN -->
    <node pkg="socketcan_bridge" name="topic_to_socket_node" type="topic_to_socket_node" output="screen">
        <param name="can_device" value="can0" />
    </node>
    <!-- CAN 转 topic -->
    <node pkg="socketcan_bridge" name="socket_to_topic_node" type="socket_to_topic_node" output="screen">
        <param name="can_device" value="can0" />
    </node>
    <!-- 示例节点 -->
    <node  pkg="can_test" name="can_test" type="can_test_node" output="screen" />
</launch>
  • C++文件,示例节点
#include <ros/ros.h>
#include <can_msgs/Frame.h>


void canCallBack(const can_msgs::Frame::ConstPtr &msg)
{
    static int times = 0;
	std::cout << times++ << "ID: " << msg->id << " data: " ;    for (int i = 0; i < msg->dlc; i++)
    {
        printf("%X ", msg->data[i]);
    }
    std::cout << std::endl;
}

int main(int argc, char **argv)
{
    setlocale(LC_ALL, "");
    ros::init(argc, argv, "can_test_node");
    ros::NodeHandle nh;
    ros::Publisher pub = nh.advertise<can_msgs::Frame>("sent_messages", 100);

    can_msgs::Frame can_frame_msg;
    can_frame_msg.id =  0x521;
    can_frame_msg.dlc = 8;
    // 分开赋值
    can_frame_msg.data[0] = 0x00;
    can_frame_msg.data[1] = 0x11;
    can_frame_msg.data[2] = 0x22;
    can_frame_msg.data[3] = 0x33;
    can_frame_msg.data[4] = 0x44;
    can_frame_msg.data[5] = 0x55;
    can_frame_msg.data[6] = 0x66;
    can_frame_msg.data[7] = 0x77;
    // can_frame_msg.data = {00, 11, 22, 33, 44, 55, 66, 77};   // 一次性全部赋值

    ros::Subscriber sub = nh.subscribe("/received_messages", 100, &canCallBack);

    ros::Rate r(1);
    while (ros::ok())
    {
        pub.publish(can_frame_msg);
        r.sleep();
        ros::spinOnce();
    }

    return 0;
}

  • 使用 cansend 命令发布数据,进行 CAN 数据转 ROS 话题数据的方法验证

查看发布的数据

  • candump can0 :查看CAN 数据
  • rostopic echo /received_messages :查看话题数据

实体 CAN 使用

CAN 口回环检测

简单含义及作用

  • 回环检测模式又称自检测模式,主要是 CAN 口自己发出的数据自己接收,数据不流经 CAN 总线
  • 这样做可以检测 CAN 口通讯是否正常,是否存在问题,排除 CAN 总线及总线上的干扰

操作流程

  • 关闭 CAN
    sudo ip link set down can0
  • 设置 CAN 口波特率,此处设置为 500Kbps
    sudo ip link set can0 type can bitrate 500000
  • 设置CAN 为回环检测模式
    sudo ip link set can0 type can loopback on
  • 使能 CAN
    sudo ip link set up can0
  • 检测并发布 CAN 数据
    candump can0
    cansend can0 521#010301000001

测试结果

  • 可以在 candump 窗口看到在发布 CAN 数据的同时又接收到一个相同的 CAN 数据
  • 如果出现上面的情况,就表示 CAN 口无误,反之需要针对输出的问题进行相应处理
    当前未遇到过问题,若有朋友遇到欢迎在评论区讨论

CAN 测试

  • 查看当前 CAN 口状态
    ip -details -statistics link show can0
  • 根据实际需求修改设置 CAN 口:波特率、是否为回环测试、时钟同步精度等,如下示例
    sudo ip link set can0 type can bitrate 500000 sjw 4 restart-ms 100 berr-reporting on

命令解析:
ip link: 这是用于操作Linux内核中网络设备链接的工具。它可以用来查看、修改或操作网络接口的各种设置。
set can0 type can: 这部分命令设置can0接口的类型为CAN接口。can0是CAN接口的名字。
bitrate 500000: 这设置了CAN接口的数据传输速率为500,000比特每秒(500 kbps)。
sjw 4: 这设置了同步跳转宽度(sjw)为4。同步跳转宽度决定了时钟同步的精度,它影响时钟同步的延迟和抖动。
restart-ms 100: 这设置了在检测到错误后重新启动通信的时间间隔为100毫秒。
berr-reporting on: 这启用了位错误报告。当这个选项被启用时,如果检测到位错误,系统会发送一个错误报告。

  • 关闭 CAN 回环检测模式
    sudo ip link set can0 type can loopback off

  • 检测并发布 CAN 数据
    candump can0
    cansend can0 521#010301000001
    此时可以使用其他 CAN 设备向 CAN 总线发布数据,使用candump查看是否存在数据


参考文章

[1] ros_canopen使用心得
[2] ROS采用SocketCAN进行通信
[3] TX2/Linux下can总线的接收与发送详解!

  • 27
    点赞
  • 60
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
基于ROS的相机和毫米波雷达是两种不同的传感器设备,它们常被用于机器人感知环境和导航任务中。 相机是一种光学传感器,能够捕捉图像并将其转换为数字信号。在ROS中,提供了一系列相机驱动包,如usb_cam和camera_calibration等,可以方便地实现相机的驱动和图像数据获取。利用相机,机器人可以获取周围环境可见光的图像信息,识别物体、进行目标定位、跟踪等任务。相机的高分辨率和颜色信息使得它在室内和室外的场景感知中都非常重要。 毫米波雷达则是一种通过发射和接收毫米波信号来感知周围环境的传感器。ROS中提供的毫米波雷达驱动包,如velodyne和livox等,可以用于连接和控制毫米波雷达设备,并获取雷达所探测到的点云数据。毫米波雷达能够提供高精度的距离和速度信息,无论是在室内还是室外环境中。它可以检测静态和动态物体,实现障碍物检测、距离测量、地图构建和导航等功能。 基于ROS的相机和毫米波雷达可以结合使用,提供更全面和准确的环境感知能力。通过将相机和毫米波雷达的数据进行融合,可以更好地理解环境,精确地定位目标和障碍物。这种感知融合的方法对于自主导航、避障以及智能交通系统等领域都具有重要意义。此外,基于ROS的相机和毫米波雷达设备还可与其他传感器如激光雷达、惯性测量单元等进行融合,进一步提升机器人的感知能力和任务执行效果。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值