赞
踩
ubuntu18.04.melodic
STM32:DJI Robomaster C板
ROS:18.04
硬件:USB-CAN(选支持Linux驱动的)
http://wiki.ros.org/socketcan_bridge
主要利用socketcan_bridge_node节点,相当于ros和stm32桥梁作用
原理解释:
Subscribed Topics
sent_messages (can_msgs/Frame)
它可以监听话题为sent_messages,消息类型为can_msgs/Frame的数据
原理解释:
Published Topics
received_messages (can_msgs/Frame)
将监听到的sent_messages话题,消息类型为can_msgs/Frame的数据发送到can总线上(以便stm32的can回调函数接收can数据)
写一个python包。发布话题为sent_messages,消息类型为can_msgs/Frame的数据
注意标识符要和stm32的一样,这里都是设置成0x208
msg.id = 0x208
msg.dlc = 8 # 数据字段的大小,单位是字节
msg.is_error = False
msg.is_rtr = False
msg.is_extended = False
再到stm32中的can回调函数解析这里的数据
data_to_send = [0x01,0x03,0x03,0x03,0x03,0x03,0x03,0x03]
如果要获取第一个数据,就data[0]这样,就可以得到0x01的值,也就算十进制的1, 我这里只是解析一位来控制电机转动
详细代码:
#!/usr/bin/env python # -*- coding: utf-8 -*- import rospy from can_msgs.msg import Frame import struct def send_can_frame(): # 初始化 ROS 节点 rospy.init_node('can_frame_sender', anonymous=True) # 创建一个发布者,发布 can_msgs/Frame 类型的消息到目标 ROS 话题 pub = rospy.Publisher('/sent_messages', Frame, queue_size=10) # 设置循环速率,这里设为 10Hz,根据需求可以调整 rate = rospy.Rate(10) while not rospy.is_shutdown(): # 创建一个 can_msgs/Frame 类型的消息 msg = Frame() # 设置 can::Frame 对象的属性,这里以设置标识符为 0x205 为例 msg.id = 0x208 msg.dlc = 8 # 数据字段的大小,单位是字节 msg.is_error = False msg.is_rtr = False msg.is_extended = False # 只解析第一位 # data_to_send = [0x04,0x03,0x03,0x03,0x03,0x03,0x03,0x03] data_to_send = [0x01,0x03,0x03,0x03,0x03,0x03,0x03,0x03] # 将要发送的数据赋值给 msg.data msg.data = data_to_send # 发布消息到 ROS 话题 pub.publish(msg) # 等待指定的循环速率 rate.sleep() # 打印成功发布的提醒消息 rospy.loginfo("Successfully published CAN frame with ID 0x208") if __name__ == '__main__': try: send_can_frame() except rospy.ROSInterruptException: pass
rx_data[0]解析得是ros发布得数据 data_to_send = [0x01,0x03,0x03,0x03,0x03,0x03,0x03,0x03],也就是得到十进制得0x01,代表数字1。
void HAL_CAN_RxFifo0MsgPendingCallback(CAN_HandleTypeDef *hcan) { // 定义CAN消息的头部和数据 CAN_RxHeaderTypeDef rx_header; uint8_t rx_data[8]; // 检查CAN总线实例是否为CAN1 if (hcan->Instance == CAN1) { // 获取CAN消息的头部信息和数据 HAL_CAN_GetRxMessage(hcan, CAN_RX_FIFO0, &rx_header, rx_data); // rx_data接收CAN总线上发送来的数据,不同的位代表不同的信息 // 根据接收到的消息的标准帧ID执行相应的处理 switch (rx_header.StdId) //如果接收的rx_header.StdId值等于0x205,则接收can发送过来的数据。可以设置ros发送的can标识符为为0x208 (ros如何发送信息到can中) { case 0x205: // 如果标准帧ID为0x205 { // 解析接收到的数据,并存储到相应的数据结构中 motor_yaw_info.rotor_angle = ((rx_data[0] << 8) | rx_data[1]); motor_yaw_info.rotor_speed = ((rx_data[2] << 8) | rx_data[3]); motor_yaw_info.torque_current = ((rx_data[4] << 8) | rx_data[5]); motor_yaw_info.temp = rx_data[6]; break; } case 0x208: { // 处理接收到的 target_yaw_angle 数据 uint8_t received_target_yaw_angle = rx_data[0]; // 假设 target_yaw_angle 在数据的第一个字节 // 在这里添加处理 received_target_yaw_angle 的代码 target_yaw_angle = received_target_yaw_angle; break; } } } }
# 安装gs_usb 内核模块
sudo modprobe gs_usb
# 插入USB-CAN后执行下面步骤:
查看can设备
ifconfig -a
# 设置波特率100M(can设备参数)-和stm32cubemx can配置的波特率一样
sudo ip link set can0 up type can bitrate 1000000
捕捉can信号
candump can0
#启动socketcan_bridge_node.cpp节点
roscore
duduzai@duduzai:~/Downloads/ros_can_ws$ source ./devel/setup.bash
duduzai@duduzai:~/Downloads/ros_can_ws$ rosrun socketcan_bridge socketcan_bridge_node
#启动python包
duduzai@duduzai:~/Downloads/target_yaw_angle_ws/src/target_yaw_angle/scripts$ chmod +x target_yaw_angle_pub.py
duduzai@duduzai:~/Downloads/target_yaw_angle_ws$ source ./devel/setup.bash
duduzai@duduzai:~/Downloads/target_yaw_angle_ws$ rosrun target_yaw_angle target_yaw_angle_pub.py
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。