MotorsBus 是串行总线上串联舵机的底层接口。机器人使用它来读取位置
并写入目标位置;除非你要添加硬件,否则很少会直接接触它。
有关添加新总线,请参阅 自带硬件, 有关特定设备的说明,请参阅 更新 Feetech 固件 和 Damiao 电机与 CAN 总线。
( port: strmotors: dict[str, Motor]calibration: dict[str, MotorCalibration] | None = None )
SerialMotorsBus 允许高效地读取和写入通过串行通信连接的电机。 它代表多个菊花链式连接并通过串口连接的电机。 目前该类有两种实现:
该类专门用于基于串行的电机协议(Dynamixel、Feetech 等)。
MotorsBus 子类的实例需要一个端口(例如 FeetechMotorsBus(port="/dev/tty.usbmodem575E0031751")。
要查找端口,你可以运行我们的实用脚本:
lerobot-find-port.py
>>> Finding all available ports for the MotorsBus.
>>> ["/dev/tty.usbmodem575E0032081", "/dev/tty.usbmodem575E0031751"]
>>> Remove the usb cable from your MotorsBus and press Enter when done.
>>> The port of this MotorsBus is /dev/tty.usbmodem575E0031751.
>>> Reconnect the usb cable.将 1 个 Feetech sts3215 电机连接到总线的用法示例:
bus = FeetechMotorsBus(
port="/dev/tty.usbmodem575E0031751",
motors={"my_motor": (1, "sts3215")},
)
bus.connect()
position = bus.read("Present_Position", "my_motor", normalize=False)
# Move from a few motor steps as an example
few_steps = 30
bus.write("Goal_Position", "my_motor", position + few_steps, normalize=False)
# When done, properly disconnect the port using
bus.disconnect()( num_retry: int = 0raise_on_error: bool = False ) → dict[int, int] | None
使用广播地址 ping 总线上的每个 ID。
( handshake: bool = True )
打开串口并初始化通信。
( motors: str | list[str] | None = Nonenum_retry: int = 0 )
禁用所选电机的力矩。
禁用力矩可以写入电机的永久存储区(EPROM/EEPROM)。
( disable_torque: bool = True )
关闭串口(可选地先禁用力矩)。
( motors: int | str | list[str] | None = Nonenum_retry: int = 0 )
启用所选电机的力矩。
返回端口上配置的当前波特率。
( motor: NameOrIDnum_retry: int = 0raise_on_error: bool = False ) → int | None
Ping 单个电机并返回其型号。
( data_name: strmotor: strnormalize: bool = Truenum_retry: int = 0 ) → Value
从电机读取一个寄存器。
( ) → dict[str, MotorCalibration]
返回
dict[str, MotorCalibration]
映射 电机名称 → calibration。
从电机读取 calibration 参数。
( motors: NameOrID | Sequence[NameOrID] | None = Nonedisplay_values: bool = True ) → tuple[dict[str, Value], dict[str, Value]]
以交互方式记录每个电机的最小/最大编码器值。
在方法实时输出位置的同时,用手移动关节(禁用力矩)。按
:kbd:Enter 完成。
( motors: NameOrID | Sequence[NameOrID] | None = None )
恢复所选电机的出厂 calibration。
零位偏移设置为 0,最小/最大位置限制设置为完整可用范围。
内存中的 :pyattr:calibration 会被清除。
( port: str*args**kwargs ) → dict[int, list[int]]
以所有支持的波特率探测 port,并列出响应的 ID。
( baudrate: int )
在端口上设置新的 UART 波特率。
( motors: NameOrID | Sequence[NameOrID] | None = None ) → dict[str, Value]
将每个电机的范围以当前位置为中心对齐。
该函数计算并写入一个零位偏移,使当前位置恰好变为
半圈(例如 12 位编码器上的 2047)。
( timeout_ms: int | None = None )
更改 SDK 使用的数据包超时时间。
( motor: strinitial_baudrate: int | None = Noneinitial_id: int | None = None )
为单个电机分配正确的 ID 和波特率。
该辅助函数会临时切换到电机的当前设置,禁用力矩,设置所需的 ID,最后写入总线的默认波特率。
( data_name: strmotors: NameOrID | Sequence[NameOrID] | None = Nonenormalize: bool = Truenum_retry: int = 0 ) → dict[str, Value]
同时从多个电机读取同一寄存器。
( data_name: strvalues: Value | dict[str, Value]normalize: bool = Truenum_retry: int = 0 )
在多个电机上写入同一寄存器。
与 :pymeth:write 不同,此方法 不 期望电机发出响应 state 包,因此
可能允许数据包丢失。它比 :pymeth:write 更快,通常应在
频率重要且丢失部分数据包可接受时使用(例如 teleoperation 循环)。
保证力矩被重新启用的上下文管理器。
在配置电机时,该辅助函数可用于暂时禁用力矩。
Examples:
with bus.torque_disabled(): … # Safe operations here … pass
( data_name: strmotor: strvalue: Valuenormalize: bool = Truenum_retry: int = 0 )
向单个电机的寄存器写入一个值。
与 :pymeth:sync_write 不同,此方法期望电机发出响应 state 包,这
提供了值已成功写入寄存器的保证。因此,它比 :pymeth:sync_write 慢,但更可靠。通常应在配置
电机时使用。
( calibration_dict: dict[str, MotorCalibration]cache: bool = True )
将 calibration 参数写入电机,并可选地缓存它们。
( id: intmodel: strnorm_mode: MotorNormModemotor_type_str: str | None = Nonerecv_id: int | None = None )
( id: intdrive_mode: inthoming_offset: intrange_min: intrange_max: int )