返回教程正文

配套源码

x.py

app/bricks/zdt_motor/commands/x.py
zdt_motor Brick:用 Python 控制一台 ZDT 电机app/bricks/zdt_motor/commands/x.py
Python93 行
"""生成 ZDT X 固件使用的速度和位置命令。

当 ``ZDTMotor`` 使用 ``firmware="x"`` 时,会自动调用本模块。
X 固件的部分速度和角度参数使用 0.1 单位,不能套用 Emm 的报文格式。
"""

from ..config import MotionMode, validate_int, validate_number
from ..errors import ZDTConfigurationError
from ..protocols.zdt import LogicalCommand
from .base import direction_and_magnitude, pack_u16, pack_u32, parse_motion_mode


def to_tenths(name, value, maximum):
    """
    @description         : 把工程单位转换为手册规定的0.1单位整数
    @param name          : 参数名称
    @param value         : 工程单位数值
    @param maximum       : 工程单位上限
    @return              : 放大10倍的整数
    """
    normalized = validate_number(name, value, 0, maximum)
    scaled = round(normalized * 10)
    if abs(scaled / 10.0 - normalized) > 1e-9:
        raise ZDTConfigurationError(f"{name} supports one decimal place")
    return scaled


def build_speed(rpm, *, direction=None, acceleration=1000, synchronized=False):
    """
    @description         : 构造X固件F6速度模式命令
    @param rpm           : 目标速度RPM,支持一位小数和有符号方向
    @param direction     : cw、ccw或None
    @param acceleration  : 加速度0至65535RPM/S
    @param synchronized  : True缓存到同步触发,False立即执行
    @return              : LogicalCommand
    """
    resolved_direction, magnitude = direction_and_magnitude(
        "rpm", rpm, direction, 3000.0
    )
    speed_tenths = to_tenths("rpm", magnitude, 3000.0)
    acceleration_value = validate_int("acceleration", acceleration, 0, 65535)
    payload = (
        bytes((resolved_direction,))
        + pack_u16(acceleration_value)
        + pack_u16(speed_tenths)
        + bytes((int(bool(synchronized)),))
    )
    return LogicalCommand(0xF6, payload, 3, "X speed mode")


def build_position(
    degrees,
    *,
    rpm,
    direction=None,
    acceleration=1000,
    deceleration=None,
    mode=MotionMode.RELATIVE_TO_CURRENT,
    synchronized=False,
):
    """
    @description         : 构造X固件FD梯形曲线位置模式命令
    @param degrees       : 目标或相对角度,支持一位小数和有符号方向
    @param rpm           : 最大速度RPM,支持一位小数
    @param direction     : cw、ccw或None
    @param acceleration  : 加速加速度0至65535RPM/S
    @param deceleration  : 减速加速度;None时等于acceleration
    @param mode          : 相对当前、相对上一目标或绝对位置
    @param synchronized  : True缓存到同步触发,False立即执行
    @return              : LogicalCommand
    """
    resolved_direction, magnitude = direction_and_magnitude(
        "degrees", degrees, direction, 429496729.5
    )
    angle_tenths = to_tenths("degrees", magnitude, 429496729.5)
    speed_tenths = to_tenths("rpm", rpm, 3000.0)
    acceleration_value = validate_int("acceleration", acceleration, 0, 65535)
    deceleration_value = validate_int(
        "deceleration",
        acceleration if deceleration is None else deceleration,
        0,
        65535,
    )
    motion_mode = parse_motion_mode(mode)
    payload = (
        bytes((resolved_direction,))
        + pack_u16(acceleration_value)
        + pack_u16(deceleration_value)
        + pack_u16(speed_tenths)
        + pack_u32(angle_tenths)
        + bytes((motion_mode, int(bool(synchronized))))
    )
    return LogicalCommand(0xFD, payload, 3, "X trapezoidal position mode")