CAN(Controller Area Network)是机器人中最常用的现场总线之一。本文涵盖 CAN 协议基础、SocketCAN 编程及常用调试工具。
CAN 总线基础
特点
- 多主模式:任意节点可在总线空闲时发送
- 仲裁机制:ID 越小优先级越高(非破坏性仲裁)
- 差分信号:CAN_H 和 CAN_L,抗干扰强
- 错误检测:CRC 校验、位错误、填充错误等
帧格式
| 帧类型 |
用途 |
| 数据帧 |
发送数据(标准帧 11bit ID,扩展帧 29bit ID) |
| 远程帧 |
请求数据 |
| 错误帧 |
检测到错误 |
| 过载帧 |
通知需要延时 |
CAN 命令速查
1 2 3 4 5 6 7 8 9 10 11 12
| ip link show
sudo ip link set can0 type can bitrate 1000000 sudo ip link set up can0
cansend can0 123#11223344AABBCCDD
candump can0
|
SocketCAN
Linux 内核提供的 CAN 编程接口,将 CAN 设备抽象为网络设备。
基本编程流程
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| #include <linux/can.h> #include <linux/can/raw.h> #include <sys/socket.h> #include <net/if.h> #include <sys/ioctl.h>
int s = socket(PF_CAN, SOCK_RAW, CAN_RAW);
struct sockaddr_can addr; addr.can_family = AF_CAN; addr.can_ifindex = if_nametoindex("can0"); bind(s, (struct sockaddr*)&addr, sizeof(addr));
struct can_frame frame; frame.can_id = 0x123; frame.can_dlc = 8; write(s, &frame, sizeof(frame));
read(s, &frame, sizeof(frame));
|
can-utils 工具集
1 2 3 4 5
| cansend can0 123#AABBCCDD candump can0 cangen can0 canplayer cansniffer can0
|
CMake 常用技巧
基本结构
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| cmake_minimum_required(VERSION 3.0) project(MyProject)
find_package(catkin REQUIRED COMPONENTS roscpp std_msgs)
include_directories(${catkin_INCLUDE_DIRS})
add_executable(my_node src/my_node.cpp) target_link_libraries(my_node ${catkin_LIBRARIES})
install(TARGETS my_node RUNTIME DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION})
|
常用变量
1 2 3 4
| ${PROJECT_NAME} ${PROJECT_SOURCE_DIR} ${CMAKE_INSTALL_PREFIX} ${catkin_INCLUDE_DIRS}
|
Cmake install
1 2 3
| install(TARGETS my_node DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION}) install(DIRECTORY launch/ DESTINATION ${CATKIN_PACKAGE_SHARE_DESTINATION}/launch) install(DIRECTORY config/ DESTINATION ${CATKIN_PACKAGE_SHARE_DESTINATION}/config)
|
常用调试命令
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| journalctl -u my_service journalctl -f
sudo prime-select query nvidia-smi
htop ps aux | grep ros
ip addr ping 192.168.1.1
|