Low-Level Communication¶
can_utils Module¶
Module Overview¶
The can_utils module provides general CAN interface utilities, including detection, enable/disable, verification, and bimanual channel pairing. Functions are designed for Linux systems and rely on the ip command and can-utils.
Feature Map¶
can_utils
├── CAN detection
│ ├── get_available_can_interfaces()
│ ├── get_all_can_interfaces()
│ ├── check_can_interface_type()
│ └── verify_can_interface()
├── CAN configuration
│ ├── enable_can_interface()
│ ├── disable_can_interface()
│ ├── enable_all_can_interfaces()
│ └── disable_all_can_interfaces()
└── CAN pairing
└── pair_can_channels()
CAN Detection Functions¶
get_available_can_interfaces¶
get_available_can_interfaces(log=None) -> List[str]
Detects enabled and usable CAN interfaces.
- Returns: e.g.
['can0', 'can1'] - Notes: only interfaces in
UPstate are returned
get_all_can_interfaces¶
get_all_can_interfaces(log=None) -> List[str]
Detects all CAN interfaces including disabled ones.
check_can_interface_type¶
check_can_interface_type(interface, log=None) -> bool
Checks whether an interface is physical CAN (True) or virtual CAN/vcan (False).
verify_can_interface¶
verify_can_interface(interface, log=None) -> bool
Verifies whether the interface is successfully enabled.
CAN Configuration Functions¶
enable_can_interface¶
enable_can_interface(interface, bitrate=1000000, loopback=False, verbose=True, log=None, password=None) -> bool
Enables a single CAN interface.
bitrate: default 1 Mbpspassword: optional sudo password for automatic privilege handling
disable_can_interface¶
disable_can_interface(interface, verbose=True, log=None, password=None) -> bool
Disables a single CAN interface.
enable_all_can_interfaces¶
enable_all_can_interfaces(bitrate=1000000, loopback=False, verbose=True, log=None, password=None) -> Dict[str, bool]
Batch-enables all detected CAN interfaces.
disable_all_can_interfaces¶
disable_all_can_interfaces(verbose=True, log=None, password=None) -> Dict[str, bool]
Batch-disables all detected CAN interfaces.
CAN Pairing Function¶
pair_can_channels¶
pair_can_channels(interfaces=None, require_even_pairs=True, log=None) -> List[Dict[str, str]]
Pairs available CAN channels for bimanual setups.
Example output:
✓ Found valid pair: right_arm can0 - left_arm can1
✓ Found valid pair: right_arm can2 - left_arm can3
Quick Function Table¶
| Function | Return Type | Purpose |
|---|---|---|
get_available_can_interfaces |
List[str] |
Enabled interfaces |
get_all_can_interfaces |
List[str] |
All interfaces |
check_can_interface_type |
bool |
Physical/virtual check |
verify_can_interface |
bool |
Interface status check |
enable_can_interface |
bool |
Enable one interface |
disable_can_interface |
bool |
Disable one interface |
enable_all_can_interfaces |
Dict[str, bool] |
Batch enable |
disable_all_can_interfaces |
Dict[str, bool] |
Batch disable |
pair_can_channels |
List[Dict[str, str]] |
Bimanual channel pairing |
Usage Example¶
System initialization¶
from openarmx_arm_driver._lib.can_utils import (
get_all_can_interfaces,
enable_all_can_interfaces,
pair_can_channels,
)
interfaces = get_all_can_interfaces()
print("CAN interfaces:", interfaces)
enable_results = enable_all_can_interfaces()
print("Enable results:", enable_results)
pairs = pair_can_channels()
print("Detected pairs:", pairs)
Safe cleanup¶
from openarmx_arm_driver._lib.can_utils import disable_all_can_interfaces
disable_all_can_interfaces()
Troubleshooting¶
Permission issue¶
Symptom: Permission denied
Solutions:
- Run with
sudo - Add current user to
dialoutgroup:
sudo usermod -aG dialout $USER
Log out and log back in for group changes to take effect.
Interface not found¶
ip link show | grep can
sudo modprobe can
sudo modprobe can_raw
sudo modprobe can_dev
dmesg | grep -i can
System Requirements¶
Software dependencies¶
sudo apt update
sudo apt install -y can-utils iproute2
Hardware requirements¶
- Linux host with CAN support
- Proper CAN adapter and driver
- Correct wiring and termination for CAN bus
Complete Source Appendix (Chinese)¶
The full original Chinese content is included below to ensure no sections are missing in the English edition.
底层通信¶
can_utils 模块¶
模块概述¶
can_utils 模块提供CAN接口的通用工具函数,包括接口检测、启用、验证等功能。所有函数均设计为在Linux系统下运行,依赖标准的ip命令和can-utils工具包。
功能概览¶
can_utils
├── CAN接口检测
│ ├── get_available_can_interfaces() # 获取已启用接口
│ ├── get_all_can_interfaces() # 获取所有接口
│ ├── check_can_interface_type() # 检查接口类型(真实/虚拟)
│ └── verify_can_interface() # 验证接口状态
├── CAN接口配置
│ ├── enable_can_interface() # 启用单个接口
│ ├── disable_can_interface() # 禁用单个接口
│ ├── enable_all_can_interfaces() # 启用所有接口
│ └── disable_all_can_interfaces() # 禁用所有接口
└── CAN通道配对
└── pair_can_channels() # 双臂CAN通道配对
CAN接口检测函数¶
get_available_can_interfaces¶
get_available_can_interfaces(log=None) -> List[str]
自动检测系统中所有可用且已启用的CAN接口。
| 参数名 | 类型 | 默认值 | 说明 |
|---|---|---|---|
log |
callable |
None |
日志函数 |
返回值: List[str]
- 可用的CAN接口列表,例如
['can0', 'can1']
from openarmx_arm_driver._lib.can_utils import get_available_can_interfaces
# 获取所有可用CAN接口
can_interfaces = get_available_can_interfaces()
print(f"可用CAN接口: {can_interfaces}")
说明:
- 依赖Linux
ip命令 - 只返回状态为UP的接口
- 检测失败返回空列表
get_all_can_interfaces¶
get_all_can_interfaces(log=None) -> List[str]
检测系统中所有的CAN接口(包括未启用的)。
| 参数名 | 类型 | 默认值 | 说明 |
|---|---|---|---|
log |
callable |
None |
日志函数 |
返回值: List[str]
- 所有CAN接口列表,例如
['can0', 'can1', 'can2']
from openarmx_arm_driver._lib.can_utils import get_all_can_interfaces
all_interfaces = get_all_can_interfaces()
print(f"所有CAN接口: {all_interfaces}")
check_can_interface_type¶
check_can_interface_type(interface, log=None) -> bool
检查CAN接口类型,判断是否为虚拟接口。
| 参数名 | 类型 | 默认值 | 说明 |
|---|---|---|---|
interface |
str |
- | CAN接口名称,如 'can0' |
log |
callable |
None |
日志函数 |
返回值: bool
True表示真实硬件接口False表示虚拟接口(vcan)
from openarmx_arm_driver._lib.can_utils import check_can_interface_type
is_real = check_can_interface_type('can0')
print(f"can0 是真实接口: {is_real}")
verify_can_interface¶
verify_can_interface(interface, log=None) -> bool
验证CAN接口是否已成功启用。
| 参数名 | 类型 | 默认值 | 说明 |
|---|---|---|---|
interface |
str |
- | CAN接口名称,如 'can0' |
log |
callable |
None |
日志函数 |
返回值: bool
True表示接口已启用(UP状态)False表示未启用或不存在
from openarmx_arm_driver._lib.can_utils import verify_can_interface
if verify_can_interface('can0'):
print("can0 已启用")
else:
print("can0 未启用")
CAN接口配置函数¶
enable_can_interface¶
enable_can_interface(interface, bitrate=1000000, loopback=False, verbose=True, log=None, password=None) -> bool
启用单个CAN接口。
| 参数名 | 类型 | 默认值 | 说明 |
|---|---|---|---|
interface |
str |
- | CAN接口名称,如 'can0' |
bitrate |
int |
1000000 |
波特率(1Mbps) |
loopback |
bool |
False |
是否启用loopback模式 |
verbose |
bool |
True |
是否显示详细信息 |
log |
callable |
None |
日志函数 |
password |
str |
None |
sudo密码,用于自动输入密码 |
返回值: bool
True表示启用成功False表示启用失败
from openarmx_arm_driver._lib.can_utils import enable_can_interface
# 手动输入密码
success = enable_can_interface('can0', bitrate=1000000)
# 自动输入密码
success = enable_can_interface('can0', bitrate=1000000, password='your_password')
if success:
print("CAN接口启用成功")
注意: "权限要求"
此函数需要sudo权限。如果提供 password 参数,将自动输入密码;否则需要手动输入
disable_can_interface¶
disable_can_interface(interface, verbose=True, log=None, password=None) -> bool
禁用单个CAN接口。
| 参数名 | 类型 | 默认值 | 说明 |
|---|---|---|---|
interface |
str |
- | CAN接口名称,如 'can0' |
verbose |
bool |
True |
是否显示详细信息 |
log |
callable |
None |
日志函数 |
password |
str |
None |
sudo密码,用于自动输入密码 |
返回值: bool
True表示禁用成功False表示禁用失败
from openarmx_arm_driver._lib.can_utils import disable_can_interface
# 手动输入密码
disable_can_interface('can0')
# 自动输入密码
disable_can_interface('can0', password='your_password')
enable_all_can_interfaces¶
enable_all_can_interfaces(bitrate=1000000, loopback=False, verbose=True, log=None, password=None) -> Dict[str, bool]
启用所有检测到的CAN接口(批量操作)。
| 参数名 | 类型 | 默认值 | 说明 |
|---|---|---|---|
bitrate |
int |
1000000 |
波特率(1Mbps) |
loopback |
bool |
False |
是否启用loopback模式 |
verbose |
bool |
True |
是否显示详细信息 |
log |
callable |
None |
日志函数 |
password |
str |
None |
sudo密码,用于自动输入密码 |
返回值: Dict[str, bool]
- 每个接口的启用结果
from openarmx_arm_driver._lib.can_utils import enable_all_can_interfaces
# 手动输入密码
results = enable_all_can_interfaces()
# 自动输入密码
results = enable_all_can_interfaces(password='your_password')
for iface, success in results.items():
print(f"{iface}: {'成功' if success else '失败'}")
disable_all_can_interfaces¶
disable_all_can_interfaces(verbose=True, log=None, password=None) -> Dict[str, bool]
禁用所有检测到的CAN接口(批量操作)。
| 参数名 | 类型 | 默认值 | 说明 |
|---|---|---|---|
verbose |
bool |
True |
是否显示详细信息 |
log |
callable |
None |
日志函数 |
password |
str |
None |
sudo密码,用于自动输入密码 |
返回值: Dict[str, bool]
- 每个接口的禁用结果
from openarmx_arm_driver._lib.can_utils import disable_all_can_interfaces
# 手动输入密码
results = disable_all_can_interfaces()
# 自动输入密码
results = disable_all_can_interfaces(password='your_password')
CAN通道配对函数¶
pair_can_channels¶
pair_can_channels(available_channels) -> List[Tuple[str, str]]
将可用的CAN通道按固定规则配对为双臂机器人。
配对规则: 偶数通道(右臂) - 奇数通道(左臂)
can0(右) -can1(左)can2(右) -can3(左)can4(右) -can5(左)- ...
| 参数名 | 类型 | 说明 |
|---|---|---|
available_channels |
List[str] |
可用的CAN通道列表,如 ['can0', 'can1'] |
返回值: List[Tuple[str, str]]
- 有效的配对组列表,格式:
[(right_arm, left_arm), ...]
from openarmx_arm_driver._lib.can_utils import pair_can_channels, get_available_can_interfaces
# 获取可用接口
available = get_available_can_interfaces()
print(f"可用接口: {available}")
# 配对为双臂
pairs = pair_can_channels(available)
for right, left in pairs:
print(f"右臂: {right}, 左臂: {left}")
# 输出示例:
# ✓ Found valid pair: right_arm can0 - left_arm can1
# ✓ Found valid pair: right_arm can2 - left_arm can3
注意: "配对说明"
- 只有当一组中的两个通道都可用时,才保留该组
- 如果只有单个通道可用(如只有can0没有can1),会给出提示但不包含在返回结果中
- 适用于自动检测并初始化多组双臂机器人
使用场景示例:
from openarmx_arm_driver import Robot
from openarmx_arm_driver._lib.can_utils import pair_can_channels, get_available_can_interfaces
# 自动检测并创建多个双臂机器人
available = get_available_can_interfaces()
pairs = pair_can_channels(available)
robots = []
for right_channel, left_channel in pairs:
robot = Robot(right_can_channel=right_channel, left_can_channel=left_channel)
robots.append(robot)
print(f"创建机器人: 右臂={right_channel}, 左臂={left_channel}")
print(f"共创建 {len(robots)} 个双臂机器人")
函数速查表¶
| 函数 | 功能 | 返回类型 | 需要sudo |
|---|---|---|---|
get_available_can_interfaces() |
获取已启用接口 | List[str] |
否 |
get_all_can_interfaces() |
获取所有接口 | List[str] |
否 |
check_can_interface_type() |
检查接口类型 | bool |
否 |
verify_can_interface() |
验证接口状态 | bool |
否 |
enable_can_interface() |
启用单个接口 | bool |
是 |
disable_can_interface() |
禁用单个接口 | bool |
是 |
enable_all_can_interfaces() |
启用所有接口 | Dict[str, bool] |
是 |
disable_all_can_interfaces() |
禁用所有接口 | Dict[str, bool] |
是 |
pair_can_channels() |
CAN通道配对 | List[Tuple] |
否 |
使用示例¶
系统初始化¶
from openarmx_arm_driver._lib.can_utils import (
get_available_can_interfaces,
enable_all_can_interfaces,
verify_can_interface
)
def initialize_can_system():
"""初始化CAN系统"""
# 1. 检查现有接口
available = get_available_can_interfaces()
print(f"已启用接口: {available if available else '无'}")
# 2. 启用所有接口
results = enable_all_can_interfaces(bitrate=1000000)
# 3. 验证结果
if all(results.values()):
print("所有接口启用成功")
else:
failed = [iface for iface, success in results.items() if not success]
print(f"部分接口启用失败: {failed}")
安全清理¶
import atexit
from openarmx_arm_driver._lib.can_utils import disable_all_can_interfaces
@atexit.register
def safe_shutdown():
"""程序退出时安全关闭所有CAN接口"""
disable_all_can_interfaces(verbose=True)
故障排除¶
权限问题¶
# 错误: Permission denied
# 解决方案1: 使用sudo
sudo python your_script.py
# 解决方案2: 添加用户到dialout组
sudo usermod -a -G dialout $USER
# 重新登录生效
接口不存在¶
# 检查CAN驱动
lsmod | grep can
# 查看内核日志
dmesg | grep -i can
# 加载CAN驱动
sudo modprobe can_raw
系统要求¶
软件依赖¶
# Ubuntu/Debian
sudo apt-get install can-utils iproute2
# 验证安装
ip link help
candump -h
硬件要求¶
- Linux操作系统(推荐Ubuntu 18.04+)
- CAN接口硬件(PCIe CAN卡、USB CAN适配器等)